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) 条件.await();

4

1 回答 1

1

为什么我需要在 onCallbackReceived() 中做 alock.lock() / unlock()。没有调用 lock() / unlock(),我得到了一个 IllegalState 异常。

您正在尝试signal一种您不拥有锁的条件。持有锁的唯一方法onCallbackReceived是调用if 时doSomething没有任何迹象表明正在发生。

我是否需要使用 while 循环将 condition.await() 包装在 waitForCallback() 中?

是的,假设您有 5 个线程在条件上停止,5 个线程在lock. 只有一个线程可以唤醒。如果当一个等待的线程最终唤醒另一个线程时该字段为空怎么办?您将需要再次检查以确保谓词仍然为真。

于 2015-11-17T19:14:40.887 回答