2
public class MyLockConditionTest {
    private final Lock alock = new ReentrantLock();
    private final Condition condition = alock.newCondition();
    private String message = null;

    public void waitForCallback() {
         alock.lock();
         try {
            // wait for callback from a remote server
            condition.await();
            doSomething(message);
         } finally {
              alock.unlock();
         }
    }

    // another thread will call this method as a callback to wake up the thread called condition.await()
    public void onCallbackReceived(String message) {
         alock.lock();
         try {
            this.message = message
            condition.signal();
         } finally {
              alock.unlock();
         }
    }
}

このコードでは、ReentrantLock と Condition を使用して、リモート サーバーからの特定のコールバックを待機するクラスを実装しています。このコードをテストして動作しているようですが、いくつか質問があります。

  1. onCallbackReceived() で alock.lock() / unlock() を実行する必要があるのはなぜですか。lock() / unlock() を呼び出さないと、IllegalState 例外が発生していました。onCallbackReceived() が別のスレッドによって呼び出されると、waitForCallback() の呼び出し元によってロックが保持されるため、混乱しています。そのため、onCallbackReceived() の alock.lock() は常に失敗します。

  2. while ループで condition.await() を waitForCallback() にラップする必要がありますか?

    while(message==null) condition.await();

4

1 に答える 1

1

onCallbackReceived() で alock.lock() / unlock() を実行する必要があるのはなぜですか。lock() / unlock() を呼び出さないと、IllegalState 例外が発生していました。

signalロックを所有していない状態にしようとしています。ロックを保持する唯一の方法は、発生している兆候がないonCallbackReceivedが呼び出された場合です。doSomething

while ループで condition.await() を waitForCallback() にラップする必要がありますか?

はい、条件で 5 つのスレッドが停止し、 で 5 つのスレッドがブロックされているとしlockます。ウェイクアップできるスレッドは 1 つだけです。待機中のスレッドが最終的にウェイクアップしたときに、別のスレッドがそのフィールドを null にした場合はどうなるでしょうか? 述語がまだ真であることを確認するために、もう一度確認する必要があります。

于 2015-11-17T19:14:40.887 に答える