Java中如何基于参数对方法进行条件性锁定?
限制runSubJobs针对同一JobModel串行执行的解决方案
问题背景
我有如下方法,用于针对传入的JobModel参数运行子任务:
public void runSubJobs(JobModel jobModel) { LOGGER.log("Start executing SubJobs for " + jobModel.getId()); for (SubJobModel subJobModel : jobModel.getSubJobs()) { run(subJobModel); } LOGGER.log("Finished executing SubJobs for " + jobModel.getId()); }
当前该方法支持多线程并行执行,但我需要添加以下限制:
runSubJobs()仅能针对不同的JobModel对象并行执行,同一业务标识的Job(即使是不同实例)不允许并行执行
我想知道:解决这个问题的最佳实践是什么?能否直接用synchronized (jobModel)包裹方法内容,像下面这样:
public void runSubJobs(JobModel jobModel) { synchronized (jobModel) { LOGGER.log("Start executing SubJobs for " + jobModel.getId()); for (SubJobModel subJobModel : jobModel.getSubJobs()) { run(subJobModel); } LOGGER.log("Finished executing SubJobs for " + jobModel.getId()); } }
解决方案分析
直接用synchronized (jobModel)的风险
这种方式能实现同一JobModel实例的串行执行,但存在明显缺陷:
- 死锁隐患:如果
JobModel对象被其他业务代码也加了同步锁,很容易引发交叉锁导致死锁。 - 锁不住同一业务Job的不同实例:如果同一业务Job对应多个
JobModel实例(比如从数据库重复加载、序列化重建),不同实例的锁是独立的,无法限制这类场景下的并行执行。 - 依赖对象稳定性:如果
JobModel实例被GC回收(极端场景)或外部代码修改了引用,可能导致锁失效或逻辑混乱。
推荐的最佳实践:基于业务标识的锁对象池
用ConcurrentHashMap维护一个以Job ID为key的锁池,每个Job ID对应一个独立的锁,这样不管JobModel实例是否相同,只要ID一致就会串行执行。示例代码如下:
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; // 类内定义锁池,全局唯一 private final ConcurrentHashMap<String, Lock> jobLockPool = new ConcurrentHashMap<>(); public void runSubJobs(JobModel jobModel) { String jobId = jobModel.getId(); // 线程安全:不存在则创建新锁 Lock jobLock = jobLockPool.computeIfAbsent(jobId, k -> new ReentrantLock()); jobLock.lock(); try { LOGGER.log("Start executing SubJobs for " + jobId); for (SubJobModel subJobModel : jobModel.getSubJobs()) { run(subJobModel); } LOGGER.log("Finished executing SubJobs for " + jobId); } finally { jobLock.unlock(); // 可选:如果确定该Job后续不会再被处理,可移除锁避免内存占用 // jobLockPool.remove(jobId, jobLock); } }
这种方案的优势:
- 完全隔离业务对象与锁对象,避免外部锁冲突导致的死锁。
- 基于Job ID锁定,确保同一业务Job无论实例是否相同,都能串行执行。
- 使用
ReentrantLock比synchronized更灵活,支持超时锁、中断锁等扩展场景。
内容的提问来源于stack exchange,提问作者Felix Schildmann
相关产品推荐
相关产品推荐

