Java多种方式实现生产者消费者模式
实现需求:两个线程交替打印1,0,打印10轮
java多线程口诀:
- 高内聚,低耦合
- 线程操作资源类
- 判断干活通知
- 防止虚假唤醒
方式一:使用synchronized和Object的wait和notifyAll方法
wait:使当前线程阻塞
notify,notifyAll唤醒当前线程
/** *两个线程交替打印1,0打印10轮 * *@authorAdministrator *@version1.02020年7月12日 *@seeProdConsumerDemo1 *@since1.0 * */ classShareData1{ publicintnumber=0; publicsynchronizedvoidincrement()throwsException{ while(number!=0){ this.wait(); } number++; System.out.println(Thread.currentThread().getName()+""+number); this.notifyAll(); } publicsynchronizedvoiddecrement()throwsInterruptedException{ while(number!=1){ this.wait(); } number--; System.out.println(Thread.currentThread().getName()+""+number); this.notifyAll(); } } publicclassProdConsumerDemo1{ publicstaticvoidmain(String[]args){ ShareData1shareData=newShareData1(); newThread(()->{ for(inti=0;i<10;i++){ try{ shareData.increment(); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } },"A").start(); newThread(()->{ for(inti=0;i<10;i++){ try{ shareData.decrement(); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } },"B").start(); } }
输出结果
A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0
方式二:使用jdk1.8的Lock和Condition
classShareData2{ privateintnumber=0; privateLocklock=newReentrantLock(); privateConditioncondition=lock.newCondition(); publicvoidincrement()throwsException{ lock.lock(); try{ while(number!=0){ condition.await(); } number++; System.out.println(Thread.currentThread().getName()+""+number); condition.signalAll(); }finally{ lock.unlock(); } } publicvoiddecrement()throwsInterruptedException{ lock.lock(); try{ while(number!=1){ condition.await(); } number--; System.out.println(Thread.currentThread().getName()+""+number); condition.signalAll(); }finally{ //TODO:handlefinallyclause lock.unlock(); } } } publicclassProdConsumerDemo2{ publicstaticvoidmain(String[]args){ ShareData2shareData=newShareData2(); newThread(()->{ for(inti=0;i<10;i++){ try{ shareData.increment(); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } },"A").start(); newThread(()->{ for(inti=0;i<10;i++){ try{ shareData.decrement(); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } },"B").start(); } }
输出结果
A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0 A1 B0
主要是熟悉Lock和Condition的使用
Lock和Condition相比于synchronized,能够精确唤醒
需求:三个线程A,B,C顺序打印,A打印5次,B打印10次,C打印15次,10轮
classShareData3{ privateintnumber=1; privateLocklock=newReentrantLock(); privateConditionc1=lock.newCondition(); privateConditionc2=lock.newCondition(); privateConditionc3=lock.newCondition(); publicvoidprint5()throwsException{ lock.lock(); try{ while(number!=1){ c1.await(); } number=2; for(inti=0;i<5;i++){ System.out.println(Thread.currentThread().getName()+""+i); } c2.signalAll(); }finally{ //TODO:handlefinallyclause lock.unlock(); } } publicvoidprint10()throwsInterruptedException{ lock.lock(); try{ while(number!=2){ c2.await(); } number=3; for(inti=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+""+i); } c3.signalAll(); }finally{ //TODO:handlefinallyclause lock.unlock(); } } publicvoidprint15()throwsInterruptedException{ lock.lock(); try{ while(number!=3){ c3.await(); } number=1; for(inti=0;i<15;i++){ System.out.println(Thread.currentThread().getName()+""+i); } c1.signalAll(); }finally{ //TODO:handlefinallyclause lock.unlock(); } } } publicclassProdConsumerDemo3{ publicstaticvoidmain(String[]args){ ShareData3shareData3=newShareData3(); newThread(()->{ try{ for(inti=0;i<10;i++){ shareData3.print5(); } }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } },"A").start(); newThread(()->{ try{ for(inti=0;i<10;i++){ shareData3.print10(); } }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } },"B").start(); newThread(()->{ try{ for(inti=0;i<10;i++){ shareData3.print15(); } }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } },"C").start(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。