0

数時間立ち往生している問題があり、その解決方法が本当にわかりません。それは非常に簡単です-私にはいくつかのスレッドがあり、そのうちの1つは他のスレッドからの信号を待つ必要があります。なんとなく、条件合図しても……何も起こらない!スレッドはまだ眠っているようです。すごく変な話なんですが、よくわからないのは私のせいかもしれません…

ここに私のコードの一部があります:

@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 に答える