如何防止消费者的微小竞争状况

时间:2012-12-10 13:38:05

标签: java concurrency race-condition

在我的应用程序中,发生了两件事:

  • 各种线程都可以创造就业机会。
  • 有一个消耗作业的功能(但不是1个不断运行的线程)。此函数由生产者启动,但已被锁定,因此它只运行一次。

例如,生成一份工作:

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");
    }

}

现在,这里有一个很小的竞争条件。如果

  • 主题A已离开while但尚未完成onceLock.unlock()
  • 线程B执行onceLock.tryLock()返回false

...线程B的作业在稍后调用triggerPass();

之前不会执行

虽然我怀疑它会让我在实​​践中遇到麻烦,但这个小差距是否会因为正确而被关闭?

2 个答案:

答案 0 :(得分:0)

我认为我已经通过将tryLock()替换为tryLock(1, TimeUnit.SECONDS)来解决这个问题。但这并不好,如果there are no more jobsunlock()之间的延迟超过1秒(并且知道数据库中发生了什么),那就不是万无一失。

答案 1 :(得分:0)

不幸的是,在这种设计中,竞争条件是不可避免的。想要它是正确的吗?你为什么不创建像iterator或queue这样的读 - 修改 - 写动作是单原子操作的东西?

public void triggerPass() {
    Job job = null; 
    while ((job = jobIterator.next()) != null) {
        doJob(job);
    }
}
相关问题