您好,欢迎访问三七文档
当前位置:首页 > 金融/证券 > 金融资料 > Java核心知识点学习----使用Condition控制线程通信
一.需求实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次.即:A-B-C---A-B-C---A-B-C二.实现1.分析在前面文章java核心知识点学习----多线程并发之线程间的通信,notify,wait,曾实现过需求两个线程间隔循环的例子.涉及到3个线程就使用之间的方法就有点麻烦了,这里借着刚学的Lock锁可以很方便实现互斥,但如何实现三个线程间的通信呢?2.实现效果3.实现代码packagecom.amos.concurrent;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/***@ClassName:ThreadSynchronizedConnect*@Description:实现线程间的通信,需求:主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次.A-B-C---A-B-C---A-B-C*@author:amosli*@email:hi_amos@outlook.com*@dateApr20,20144:39:44PM*/publicclassThreeConnect{(String[]args){finalBusinessbusiness=newBusiness();newThread(newRunnable(){publicvoidrun(){for(inti=0;i3;i++){business.sub2(i);}}}).start();newThread(newRunnable(){publicvoidrun(){for(inti=0;i3;i++){business.sub3(i);}}}).start();for(inti=0;i3;i++){business.main(i);}}staticclassBusiness{Locklock=newReentrantLock();Conditionconditionmain=lock.newCondition();Conditionconditionsub2=lock.newCondition();Conditionconditionsub3=lock.newCondition();privateintcurrent=1;//子方法2publicvoidsub2(inti){lock.lock();try{if(current!=2){//如果不为true,将等待,Blocked状态try{conditionsub2.await();}catch(InterruptedExceptione){e.printStackTrace();}}for(intj=0;j2;j++){System.out.println(sub2thread:+j+loop:+i);}current=3;conditionsub3.signal();//唤醒3}finally{lock.unlock();}}//子方法3publicvoidsub3(inti){lock.lock();try{if(current!=3){//如果不为true,将等待,Blocked状态try{conditionsub3.await();}catch(Exceptione){e.printStackTrace();}}(intj=0;j2;j++){System.out.println(sub3thread:+j+loop:+i);}current=1;conditionmain.signal();}finally{lock.unlock();}}//主方法publicvoidmain(inti){lock.lock();try{if(current!=1){try{conditionmain.await();}catch(Exceptione){e.printStackTrace();}}for(intj=0;j3;j++){System.out.println(mainthread:+j+loop:+i);}current=2;conditionsub2.signal();}finally{lock.unlock();}}}}4.代码说明上面的代码中用的是Lock进行加锁操作的,然后线程间的通信没有用之前的wait(),notify()方法用的是Conditon的await()和signal()为什么要使用Condition??如果程序中不使用synchronized关键字来保证同步,而是使用Lock对象来保证数据同步,则系统中不存在隐式的同步监视器,也就不能使用wait().notify()方法进行线程通信了.因为使用了Lock对象,所以要使线程间通信,可以使用Condition进行控制线程间通信.Condition将同步监视器方法(wait(),notify(),notifyall()等)分解成截然不同的对象,以便通过将这些对象与Lock对象组合使用,为每个对象提供多个等待集(wait-set).创建一个Condition,只需要lock.newCondition()即可,lock是已经new好的ReentrantLock()对象.await()方法与wait()功能类似,都是将线程加入到阻塞状态.signal()方法与notify()方法类似,都是唤醒等待中的线程,只是signal()方法可以指定具体要唤醒的线程.signalAll()方法与notifyAll()方法类似,都是唤醒所有等待中的线程.5.扩展1).下面是简单的对比,notify和signal等方法的对比,其效果是完全一样的.packagecom.amos.concurrent;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/***@ClassName:ConditionConnect*@Description:用condition替代wait,notify实现线程间的通信,需求:子线程循环10次,主线程循环100次,这样间隔循环50次.*@author:amosli*@email:hi_amos@outlook.com*@dateApr24,201412:07:23AM*/publicclassConditionConnect{publicstaticvoidmain(String[]args){finalBusinessbusiness=newBusiness();newThread(newRunnable(){publicvoidrun(){for(inti=0;i5;i++){business.sub(i);}}}).start();for(inti=0;i5;i++){business.main(i);}}/**经验:要用到共同数据(包括同步锁)的若干方法,应该归在同一个类身上,这样方便实现,高类聚和程序的健状性上.*/staticclassBusiness{privatebooleanis_sub=true;Locklock=newReentrantLock();Conditioncondition=lock.newCondition();//子方法publicvoidsub(inti){lock.lock();try{while(!is_sub){//如果不为true,将等待,Blocked状态try{//this.wait();condition.await();}catch(Exceptione){e.printStackTrace();}}for(intj=0;j2;j++){System.out.println(subthread:+j+loop:+i);}is_sub=false;//this.notify();//唤醒正在等待的线程condition.signal();}finally{lock.unlock();}}//主方法publicvoidmain(inti){lock.lock();try{while(is_sub){try{//this.wait();condition.await();}catch(Exceptione){e.printStackTrace();}}for(intj=0;j10;j++){System.out.println(mainthread:+j+loop:+i);}is_sub=true;//this.notify();condition.signal();}finally{lock.unlock();}}}}2).官方提供的例子做了简单的修改:先看效果:再看代码:packagecom.amos.concurrent;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/***@ClassName:ConditionTest*@Description:官方提供的例子*@author:amosli*@email:hi_amos@outlook.com*@dateApr24,201412:40:58AM*/publicclassConditionTest{publicstaticvoidmain(String[]args)throwsException{BoundedBufferbuffer=newBoundedBuffer();buffer.put(hi_amos);for(inti=0;i3;i++){buffer.put(i);System.out.println(take:+buffer.take());}}staticclassBoundedBuffer{finalLocklock=newReentrantLock();finalConditionnotFull=lock.newCondition();finalConditionnotEmpty=lock.newCondition();finalObject[]items=newObject[100];intputptr,takeptr,count;//设值publicvoidput(Objectx)throwsInterruptedException{lock.lock();try{while(count==items.length)notFull.await();items[putptr]=x;if(++putptr==items.length)putptr=0;++count;notEmpty.signal();}finally{lock.unlock();}}//取值publicObjecttake()throwsInterruptedException{lock.lock();try{while(count==0)notEmpty.await();Objectx=items[takeptr];if(++takeptr==items.length)takeptr=0;--count;notFull.signal();returnx;}finally{lock.unlock();}}}}思考:例子中为什么要new2个con
本文标题:Java核心知识点学习----使用Condition控制线程通信
链接地址:https://www.777doc.com/doc-2878756 .html