多线程——Condition的介绍以及⽤法
之前总结了wait和notify的⽤法,今天总结⼀下condition的⽤法。
Condition介绍:
关键字synchronize可以与wait()和nitify()⽅法相结合实现实现等待/通知模式,类ReentrantLock也可以实现同样的功能,但需要借助condition对象。condition类是在JDK5中出现的技术,使⽤他有更好的灵活性,⽐如可以实现多路通知功能,也就是在⼀个Lock对象⾥可以创建多个condition实例,线程对象可以注册在指定的condition中从⽽选择性的进⾏线程通知,在调度线程上更加灵活。
⽽在使⽤notify()/notifuAll()⽅法进⾏通知时,被调度的线程却是由JVM随机选择的。但使⽤ReentrantLock结合condition类是可以实现上⾯讲的“选择性通知”,这个功能是⾮常重要的,⽽且在condition类中默认提供的。
⽽synchronize就相当于整个Lock对象中只有⼀个单⼀的condition对象,所有的线程都注册在它⼀个对象上。线程开始notifyAll()时,需要通知所有的WAITING线程,没有选择权,会出现相当⼤的效率问题。
Condition是个接⼝,基本的⽅法就是await()和signal()⽅法
Condition依赖于Lock接⼝,⽣成⼀个Condition的基本代码是wCondition()左传全文及译文
调⽤Condition的await()和signal()⽅法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使⽤
Conditon中的await()对应Object的wait();
西南交通大学邮箱
Condition中的signal()对应Object的notify();
Condition中的signalAll()对应Object的notifyAll()。
等待/通知模式:
demo如下:
个人教学工作总结
运⾏结果:
中国几大战区
从运⾏结果来看,实现了⼀个最简单的等待/通知模式。实现通知部分线程:
两个线程类:
mian函数如下:
运⾏结果如下:
从运⾏结果看出来,两个线程最终只唤醒了线程A,线程B没有被唤醒,实现了使⽤condition通知部分线程。
还可以使⽤condition实现⽣产者/消费者模式,有兴趣的可以⾃⼰去查查看。
Condition实现分析
Condition 是⼀个接⼝,由ConditionObject 类实现,并且它还是AQS(AbstractQueuedSynchronizer)的内部类。
从源码中可以看到,每个Condition对象都包含有⼀个FIFO队列,等待队列和同步队列⼀样,使⽤的都是同步器 AQS 中的节点类 Node,同样拥有⾸节点和尾节点。
await()⽅法:
调⽤ Condition 的 await() ⽅法会使线程进⼊等待队列,并释放锁,线程状态变为等待状态。流量领取
分析上述⽅法的⼤概过程:
1. 先将当前线程包装创建为节点。
2. 释放当前线程占有的锁,
灰树花怎么吃3. while循环判断当前节点是否存在队列中,
3.1 如果没有则阻塞,继续while判断
妈妈的情人23.2如果存在,则退出while循环,执⾏下⾯的代码
4. 此时说明节点已经在同步队列中,调⽤acquireQueude⽅法,重新开始竞争锁,
5. 得到锁后返回,退出该⽅法。
signal()⽅法:
调⽤ Condition 的 signal() ⽅法,可以唤醒等待队列的⾸节点,唤醒之前会将该节点移动到同步队列中。时光匆匆的句子
分析上述⽅法⼤概过程:
1.先判断当前线程是否有锁,
2.然后对⾸节点调⽤doSignal()⽅法。
1.修改⾸节点,直到获取到为取消的节点,
2.调⽤transferForSignal⽅法。