聊聊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();  }  }}}

0 0
原创粉丝点击