Java 重入锁定条件

Java 重入锁定条件,java,multithreading,conditional-statements,reentrantlock,Java,Multithreading,Conditional Statements,Reentrantlock,我使用ReentrantLock和Condition实现了一个类来等待来自远程服务器的某些回调。我测试了这段代码,看起来很有效,但我有几个问题 为什么我需要在onCallbackReceived()中执行lock.lock()/unlock()。没有调用lock()/unlock(),我得到了一个非法状态异常。我很困惑,因为当另一个线程调用onCallbackReceived()时,waitForCallback()的调用方持有锁,所以onCallbackReceived()中的lock()总是

我使用ReentrantLock和Condition实现了一个类来等待来自远程服务器的某些回调。我测试了这段代码,看起来很有效,但我有几个问题

  • 为什么我需要在onCallbackReceived()中执行lock.lock()/unlock()。没有调用lock()/unlock(),我得到了一个非法状态异常。我很困惑,因为当另一个线程调用onCallbackReceived()时,waitForCallback()的调用方持有锁,所以onCallbackReceived()中的lock()总是会失败

  • 是否需要将waitForCallback()中的condition.await()与while循环包装在一起

    while(message==null) 条件wait()

  • 为什么我需要在onCallbackReceived()中执行lock.lock()/unlock()。没有调用lock()/unlock(),我得到了一个非法状态异常

    您正试图在您不拥有锁的情况下发出信号。保持锁的唯一方法是从
    doSomething
    调用
    onCallbackReceived
    ,但没有发生任何指示

    是否需要将waitForCallback()中的condition.await()与while循环包装在一起


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

    1)等待条件需要一个互斥锁,以防止条件以不安全的方式更改(可见性)。2) 虚假唤醒等,也为完全相同的低水平感谢您的评论。onCallbackReceived不是从doSomething doSeomthing调用的。还有一个线程引用了这个类对象,线程调用onCallbackReceived,这就是我不理解的。该锁由waitForCallback的调用方持有,但onCallbackReceived仍然可以获取锁并能够到达signal(),因此,您是说两个线程同时持有
    ?authCallbackLock.isLocked()和authCallbackLock.ishellByCurrentThread()在onCallbackReceived()中,在alock.lock()之前给我“false”虽然waitForCallback()中的alock.lock()之后authCallbackLock.isLocked()为true,但运行速度非常快。您不应该将成功建立在
    被锁定的时间上。您应该拥有两个线程
    Thread.sleep(1000000L)
    ,同时保持锁定,并在睡眠前编写调试。如果在进入睡眠前两个线程都没有记录,则只有一个线程成功。
    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();
             }
        }
    }