Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java retentrantlock.lock()不';不要阻塞其他线程_Java_Multithreading_Concurrency_Reentrantlock - Fatal编程技术网

Java retentrantlock.lock()不';不要阻塞其他线程

Java retentrantlock.lock()不';不要阻塞其他线程,java,multithreading,concurrency,reentrantlock,Java,Multithreading,Concurrency,Reentrantlock,我很难理解ReentrantLock.lock()的行为 我有以下课程 import java.util.concurrent.locks.*; class BlockingClass { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void a() { lock.lock();

我很难理解ReentrantLock.lock()的行为

我有以下课程

import java.util.concurrent.locks.*;

class BlockingClass {

    private Lock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    public void a() {
        lock.lock();
        System.out.println("called in method a(): lock()");

        try {
            System.out.println("called in method a(): await()");
            condition.await();
        } 
        catch (InterruptedException e) {} 
        finally {
            lock.unlock();
            System.out.println("called in method a(): unlock() ");
        }
    }

    public void b() {
        lock.lock();
        System.out.println("called in method b(): lock()");

        System.out.println("called in method b(): signalAll()");
        condition.signalAll();

        lock.unlock();
        System.out.println("called in method b(): unlock() ");
    }
}
我通过以下测试运行了它:

class BlockingClassTest {
    public static void main(String[] args) throws InterruptedException {

        final BlockingClass blockingClass = new BlockingClass();

        new Thread() {
            public void run() {
                System.out.println("Thread1 calling a()");
                blockingClass.a();
            }
        }.start();

        Thread.sleep(1000); 

        new Thread() {
            public void run() {
                System.out.println("Thread2 calling b()");
                blockingClass.b();
            }
        }.start();
    }
}
我原以为会出现僵局。一旦a()方法调用lock.lock(),我希望调用b()方法的任何人都必须在b的lock.lock()处等待,直到调用a()的线程调用lock.unlock()。但由于a()正在等待b()调用condition.signalAll(),所以这两个方法应该一直处于阻塞状态

相反,这是我在控制台中得到的输出:

Thread1 calling a()
called in method a(): lock()
called in method a(): await()
Thread2 calling b()
called in method b(): lock()
called in method b(): signalAll()
called in method a(): unlock() 
called in method b(): unlock() 

我对lock()和unlock()的正确使用和功能有什么误解?

你没有误解可重入锁,你误解了条件。
条件
绑定到锁,而
条件。wait()
将有效解锁、检查并等待,然后重新锁定锁。看

a()。在对
await()
的调用中,
条件正在管理它

这是“条件变量”一般概念的一部分;这就是为什么您找到的任何线程库都会将某种锁与条件相关联(例如,在POSIX C中,需要条件变量和互斥)


查看上的维基百科文章,它详细解释了这种行为及其原因。

您对
条件的调用。wait()
将释放锁,使线程处于
等待
状态,因此线程b可以获取锁


您的
a()
方法将在
b()
释放其锁后继续运行,因为您发出了条件信号。

答案已经给出,但我想我只需引用以下内容来提供更多上下文:

使当前线程等待,直到发出信号或中断

与此条件相关联的锁以原子方式释放,当前线程出于线程调度目的被禁用,并处于休眠状态,直到发生以下四种情况之一:

  • 其他一些线程为此条件调用signal方法,而当前线程恰好被选为要唤醒的线程;或
  • 其他一些线程为此条件调用signalAll方法;或
  • 其他线程中断当前线程,支持中断线程挂起;或
  • 出现“虚假唤醒”
  • 在所有情况下,在该方法返回之前,当前线程必须重新获取与此条件关联的锁。当线程返回时,保证持有该锁


    因此,当您调用
    condition.await()
    时,它会释放锁,允许另一个线程进入锁定部分。这与
    Object.wait()
    synchronized
    代码块内部时的行为相同。

    如何解释
    a()解锁()
    发生在
    b()解锁()
    之前的事实?这是代码中的竞态条件。
    System.out.println(“…”)方法被同时调用,因为不再获取锁。^您可以在
    unlock()
    调用之前放置一个打印输出,以查看操作顺序的更准确视图,@SotiriosDelimanolisThanks、@ortang和Jason C,以获得您出色且快速的答案。我接受这篇文章仅仅是因为它的完整性和有用的文档。感谢您对
    Object.wait()
    的参考。这也很有帮助。