You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让调用阻塞synchronized方法的线程直接执行后续代码?

实现非阻塞式的processList方法

你的核心需求是让线程调用processList()时,不用等着锁释放,拿不到锁就直接去做别的事——用Java的ReentrantLock就能搞定,替代原来的synchronized方法就行。

具体实现步骤

下面是修改后的ListHolder代码:

import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;

public class ListHolder {
    private final ArrayList<Object> list = new ArrayList<>();
    // 声明显式锁,替代synchronized方法的隐式锁
    private final ReentrantLock processLock = new ReentrantLock();

    // 原有的addObject方法保持不变,维持原有线程安全逻辑
    public void addObject(Object obj) {
        synchronized (list) {
            list.add(obj);
        }
    }

    // 修改为非阻塞的processList方法
    public void processList() {
        // 尝试获取锁,成功返回true,失败直接返回false,不会阻塞线程
        if (processLock.tryLock()) {
            try {
                // 操作list时仍需与addObject保持同步,避免并发修改异常
                synchronized (list) {
                    if (!list.isEmpty()) {
                        // 这里编写你的列表处理逻辑,比如遍历元素、执行业务操作
                        for (Object obj : list) {
                            // 处理对象的具体代码
                        }
                        list.clear();
                    }
                }
            } finally {
                // 无论是否出现异常,必须释放锁,防止死锁
                processLock.unlock();
            }
        }
        // 拿不到锁时直接执行后续代码,线程可去构造新对象,无需等待
    }
}

关键细节说明

  • tryLock()是核心:它不会像synchronized那样让线程挂起等待,而是立刻判断能否获取锁,拿不到就直接走后续逻辑,完全匹配你的效率需求。
  • 操作list的同步块不能省略:因为addObject()是以list作为锁对象的,处理list时必须使用同一锁,否则会出现并发修改的问题。
  • 锁必须在finally块释放:万一处理逻辑抛出异常,finally块能保证锁被释放,避免其他线程永远无法获取锁的情况。

如果你的场景需要短暂等待后再放弃(比如等待100毫秒),可以使用带超时参数的tryLock(100, TimeUnit.MILLISECONDS),但根据你的需求,直接使用无参的tryLock()就足够了。

内容的提问来源于stack exchange,提问作者Andikan Otung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 03:55:14