聊聊Condition
来源:互联网 发布:电脑桌面壁纸 知乎 编辑:程序博客网 时间:2024/04/29 02:38
本文可作为传智播客《张孝祥-Java多线程与并发库高级应用》的学习笔记。
上面我们说了Lock,那是对synchronized的一种更为面向对象的替代,在原来的synchronized内部,我们可以调用object的wait与notify方法,那么使用lock之后,如何进行线程的通信呢。
对锁不清楚的朋友可以看看
http://blog.csdn.net/dlf123321/article/details/42919085
答案是condition。
condition一方面是对lock功能的补充(也就是说,你用了lock,为了保证线程的通信,就得用condition)
另一方面,synchronized的notifyall是唤醒所有等待的线程,那么如果有些线程我不想唤醒呢。
看下面这个例子
主线程运行10次,然后子线程2运行20次,接着子线程3运行30次
上面的整体运行4次。
我们分析一下,主线程运行10次之后,下面一方面让自己阻塞,同时应该唤醒子线程2,并且不能唤醒子线程3。
如果用notifyAll就等于把线程2与线程3都唤醒了。
我们在这里说明一下
Reentrantlock相比较于synchronized还少有三个优势
1 等待可中断 具体的例子参考 http://uule.iteye.com/blog/1488356
2 实现公平锁 就是线程a在操作某个对象,线程b,c,d后面又依次来了,如果是非公平锁,那么等a结束后,bcd接手的概率是一样的,如果是公平锁那么a完了之后就是b
synchronized是非公平的是,Reentrantlock默认情况下也是非公平的,但可以通过有带Boolean只的构造函数构建一个公平锁
3 绑定多个条件 也就是下面讲的
4 有三种使用方式
a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
c)tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
参考资料 http://houlinyan.iteye.com/blog/1112535
另外我得说明一点
就性能来说,在java6之后,reentrantlock与synchronized已经差不多了
而且Reentrantlock得主动释放
所有到底选择哪个实现互斥,大家还是得考虑一下
看看方法
常用的就是await与signal。
这个两个就刚好对应object的wait与notify。
我们看代码:
package cn.itcast.heima2;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ThreeConditionCommunication {/** * @param args */public static void main(String[] args) {final Business business = new Business();new Thread(new Runnable() {@Overridepublic void run() {for(int i=1;i<=4;i++){business.sub2(i);}}}).start();new Thread(new Runnable() {@Overridepublic void run() {for(int i=1;i<=4;i++){business.sub3(i);}}}).start();for(int i=1;i<=4;i++){business.main(i);}}static class Business {Lock lock = new ReentrantLock();Condition condition1 = lock.newCondition();Condition condition2 = lock.newCondition();Condition condition3 = lock.newCondition(); private int shouldSub = 1; public void sub2(int i){ lock.lock(); try{ while(shouldSub != 2){ try {condition2.await();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }for(int j=1;j<=20;j++){System.out.println("sub2 thread sequence of " + j + ",loop of " + i);} shouldSub = 3; condition3.signal(); }finally{ lock.unlock(); } } public void sub3(int i){ lock.lock(); try{ while(shouldSub != 3){ try {condition3.await();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }for(int j=1;j<=30;j++){System.out.println("sub3 thread sequence of " + j + ",loop of " + i);} shouldSub = 1; condition1.signal(); }finally{ lock.unlock(); } } public void main(int i){ lock.lock(); try{ while(shouldSub != 1){ try {condition1.await();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }for(int j=1;j<=10;j++){System.out.println("main thread sequence of " + j + ",loop of " + i);}shouldSub = 2;condition2.signal(); }finally{ lock.unlock(); } }}}
- 聊聊Condition
- Condition
- Condition
- Condition
- Condition
- Condition
- Condition
- Condition
- Condition
- Condition
- 聊聊
- 聊聊
- 聊聊
- 聊聊
- 聊聊高并发(十四)理解Java中的管程,条件队列,Condition以及实现一个阻塞队列
- boost condition
- boost condition
- race condition
- ORACLE用SYS登录报ORA-28009:connection as SYS should be as SYSDBA OR SYSOPER解决方法
- Spring DI[依赖注入]
- java基础学习(4)
- 剑指offer之面试题4替换空格
- 1005
- 聊聊Condition
- oracle赋权
- SQL中数据库的基本操作
- 第11周阅读程序(5-4)
- python正则表达式
- [bzoj4552][TJOI&HEOI2016]排序
- 8+2时间制
- mysql删除数据不能带表名
- C++作业5