我有一个问题,我被困了几个小时,我真的不知道如何解决它。这很简单 - 我有一些线程,其中一个需要等待来自另一个的信号。不知何故,即使我在一个条件下发出信号......也没有任何反应!看起来线程还在睡觉。这是一个非常奇怪的问题,但我不明白这一点可能是我的错......
以下是我的代码的一部分:
@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,而“我醒来”从来没有......
任何想法,如何解决或检查什么?我几乎尝试了一切......
感谢您的时间和帮助!
答案 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,因为该人知道如何使用并发。