Java,Lock,Condition - 信号没有唤醒等待线程

时间:2015-04-26 19:55:42

标签: java multithreading conditional-statements reentrantlock

我有一个问题,我被困了几个小时,我真的不知道如何解决它。这很简单 - 我有一些线程,其中一个需要等待来自另一个的信号。不知何故,即使我在一个条件下发出信号......也没有任何反应!看起来线程还在睡觉。这是一个非常奇怪的问题,但我不明白这一点可能是我的错......

以下是我的代码的一部分:

@Override
public void bodyProduced() {
    lock.lock();
    producedBodies++;
    if (producedEngines == 0) {
        while(producedEngines==0)
        {
            System.out.println("I am still waiting!");
            body.awaitUninterruptibly();
        }
        System.out.println("I waked up!");
        producedBodies--;
        producedEngines--;
    } else {
        engine.signalAll();
    }
}

我确信body.signalAll();当有线程等待那个条件时调用 - 我检查并且调试器多次遍历该行。然而,“我在等待”这一行只出现一次对于thraad,而“我醒来”从来没有......

任何想法,如何解决或检查什么?我几乎尝试了一切......

感谢您的时间和帮助!

2 个答案:

答案 0 :(得分:3)

使用ReentrantLock时,必须在关键部分后调用unlock()。这必须在finally子句

中完成
lock.lock();
try{
 // critical section code (may throw exception)
} finally {
  lock.unlock();  
}

如果你不这样做(就像你的代码一样),没有线程可以进入这个部分,因为它(正确地)假设这个部分仍然被锁定。您必须明确解锁它以允许其他线程进入。

答案 1 :(得分:2)

如果您使用共享锁,您可能还需要在某个时候发布它。否则只有第一个线程能够越过第一行,其他线程将停止等待释放锁。

一旦你修复了锁定的东西,只要它们不是易失性的,你的yieldBodies和generatedEngines的增量和减量可能都不会很好。

无论如何,并发总是一个很难的主题,一般来说,最好不要写这些代码。无论何时你想到,你已经解决了并发问题,你很可能只看到了冰山一角。

在你的情况下,我建议,考虑使用Synchronized,CountDownLatch或ExecutorServices? (你还没有真正描述过你的问题)。如果JDK附带的所有功能都不适合您,那么请同时查看Heinz Kabutz's java newsletter,因为该人知道如何使用并发。