Java retentrantlock.lock()不';不要阻塞其他线程
我很难理解ReentrantLock.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();
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()
的参考。这也很有帮助。