【问题标题】:Java, Lock, Condition - Signal not waking waiting threadJava,锁定,条件 - 信号未唤醒等待线程
【发布时间】:2015-07-05 03:21:14
【问题描述】:

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

这是我的代码的一部分:

@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 中只出现一次,而“我醒来”则从未出现过......

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

感谢您的宝贵时间和帮助!

【问题讨论】:

    标签: java multithreading conditional-statements reentrantlock


    【解决方案1】:

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

    一旦你修复了锁,只要它们不是易失性的,你对producedBodies和producerEngines的增量和减量可能不会很好地工作。

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

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

    【讨论】:

    • 感谢您的回复。我知道 volatile 的东西,我在这里使用它。所以这不是问题。好吧,这是我学习任务的一部分,所以我不得不在这里使用锁定/条件。看起来问题是我必须先解锁,只有在我解锁后才会唤醒另一个线程。很奇怪,因为我不想让醒来后的部分被同步。
    【解决方案2】:

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

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

    如果您不这样做(如在您的代码中),则没有线程能够进入此部分,因为它(正确地)假定此部分仍处于锁定状态。您必须明确解锁它才能允许其他线程进入。

    【讨论】:

    • 我知道这一点,但在我的情况下,锁是用其他方法解锁的。我想要实现的是: 1. 线程在关键部分 2。它唤醒另一个线程,被唤醒的线程已经在它的关键部分之外,但第一个仍然继续做同步的事情。
    • 发布您的整个代码,以便我们完全理解问题所在。您可以简单地编辑您的问题并添加更多详细信息。希望这会有所帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 2019-09-27
    相关资源
    最近更新 更多