当前位置: 首页 > 后端技术 > Java

JUC第七条件

时间:2023-04-01 22:45:33 Java

任何Java对象都有一个一级监听方法,比如wait()、notify()等,这些方法需要和synchronized配合使用,实现等待通知功能。SimilarConditions也提供了相应的方法。Condition作为一个接口,只定义了一些模板方法,实现在AbstractQueuedSynchronizer的内部类ConditionObject中。以下是Condition中的方法:简单说明一下,在调用上述方法之前,需要先获取Condition关联的锁。锁lock=newReentrantLock();Condition条件=lock.newCondition();调用await()方法后,当前线程会释放锁等待,同时其他线程调用Condition对象的signal()方法通知当前线程,当前线程获取到锁后,会从等待()方法。也就是说,解释就是获取锁的线程发现某个条件不满足不能继续执行,而该条件需要其他线程对共享资源进行操作才能触发,所以必须释放锁。实现分析等待队列在conditionObject对象中维护了一个先进先出的等待队列,队列中的每个节点都包含一个线程引用,即等待条件对象的线程。条件包含等待队列。该条件有一个第一个节点(firstWaiter)和一个尾节点(lastWaiter)。当线程调用await()方法时,会用当前线程构造一个节点,并添加到队列的尾部。在Objectmonitor模式下,一个对象有一个同步队列和一个等待队列,一个Lock同步器有一个同步队列和多个等待队列。Waiting调用await()方法时,会使用当前线程进入等待队列并释放锁,线程状态变为等待状态。从await()返回时,当前线程必须已经获取了锁。注意,当调用signal()方法时,只有当前线程获取到锁后,等待队列中等待时间最长的节点(第一个节点)才会被唤醒。在唤醒节点之前,节点会被移动到同步队列中,并使用LockSupport唤醒节点中的线程。Condition中的signalAll()方法相当于对等待队列中的每个节点执行一次signal()方法,将等待队列中的所有节点移动到同步队列中,并唤醒每个节点的线程。使用场景使用Condition实现等待通知模式,一些特殊的等待队列等。阻塞队列底层使用Condition的等待通知模式实现:当向满队列添加元素时,此时线程会被阻塞;当队列为空再从中取元素时,线程也会被阻塞。源码分析可以看这篇文章:源码分析:②ReentrantLockConditionLockCondition参考文章:《Java并发编程的艺术》