聊聊Condition

               

本文可作为传智播客《张孝祥-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() {          @Override     public void run() {           for(int i=1;i<=4;i++){       business.sub2(i);      }           }    }  ).start();    new Thread(    new Runnable() {          @Override     public 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 block      e.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 block      e.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 block       e.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();    }   }  }}

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/qq_43678748/article/details/86227755