在我的应用程序中,发生了两件事:
例如,生成一份工作:
addJobToDatabase(...);
triggerPass();
这就是消费者功能的启动方式:
public void triggerPass() {
// prevent running more than once
if (onceLock.tryLock()) { // onceLock is a ReentrantLock
try {
while (haveJobs()) {
doJobs();
}
} finally {
onceLock.unlock();
}
} else {
log.info("Pass triggered, but already running");
}
}
现在,这里有一个很小的竞争条件。如果
while
但尚未完成onceLock.unlock()
onceLock.tryLock()
返回false ...线程B的作业在稍后调用triggerPass();
之前不会执行虽然我怀疑它会让我在实践中遇到麻烦,但这个小差距是否会因为正确而被关闭?
答案 0 :(得分:0)
我认为我已经通过将tryLock()
替换为tryLock(1, TimeUnit.SECONDS)
来解决这个问题。但这并不好,如果there are no more jobs
和unlock()
之间的延迟超过1秒(并且知道数据库中发生了什么),那就不是万无一失。
答案 1 :(得分:0)
不幸的是,在这种设计中,竞争条件是不可避免的。想要它是正确的吗?你为什么不创建像iterator或queue这样的读 - 修改 - 写动作是单原子操作的东西?
public void triggerPass() {
Job job = null;
while ((job = jobIterator.next()) != null) {
doJob(job);
}
}