0

我有一个问题,我被困了几个小时,我真的不知道如何解决它。这很简单——我有一些线程,其中一个需要等待来自另一个的信号。不知何故,即使我在某个条件下发出信号……什么也没有发生!看起来线程仍在休眠。这真是一个奇怪的问题,但我不太了解某些东西可能是我的错......

这是我的代码的一部分:

@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(); 当有线程在该条件下等待时调用 - 我检查并调试器多次遍历该行。然而,“我在等待”这句话只出现一次,“我醒来”从未出现过。

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

感谢您的时间和帮助!

4

2 回答 2

3

当您使用ReentrantLock时,您必须在临界区之后调用 unlock()。这必须在 finally 子句中完成

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

如果您不这样做(就像在您的代码中那样),则没有线程能够进入该部分,因为它(正确地)假定该部分仍然被锁定。您必须明确解锁它以允许其他线程进入。

于 2015-04-26T20:06:21.370 回答
2

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

此外,一旦您修复了锁定问题,只要它们不是易失性的,您的生产体和生产引擎的增量和减量可能就不会很好地工作。

无论如何,并发总是一个很难的话题,通常不要自己编写这样的代码是一个很好的做法。每当您认为解决了并发问题时,您很可能只看到了冰山一角。

在您的情况下,我建议您考虑使用 Synchronized、CountDownLatch 还是 ExecutorServices?(您还没有真正清楚地描述您遇到的问题)。如果 JDK 附带的所有功能都不适合您,那么还请查看Heinz Kabutz 的 Java 时事通讯,因为他知道如何使用并发。

于 2015-04-26T20:06:02.550 回答