Java并发编程线程间通讯实现过程详解
在Java中线程间通讯有多种方式,我这里列出一些常用方式,并用代码的方式展示他们是如何实现的:
- 共享变量
- wait,notify,notifyAll(这3个方法是Object对象中的方法,且必须与synchronized关键字结合使用)
- CyclicBarrier、CountDownLatch
- 利用LockSupport
- Lock/Condition机制
- 管道,创建管道输出流PipedOutputStream和管道输入流PipedInputStream
示例一:
packagecom.zhi.test; importjava.util.concurrent.CountDownLatch; importjava.util.concurrent.atomic.AtomicInteger; importorg.junit.Test; /** *Java多线程-线程通讯示例
*flag作为共享变量JobB执行,notify通知Job执行,CountDownLatch通知主线程执行 * *@author张远志 *@since2020年5月4日21:51:24 * */ publicclassThreadTest2{ privateCountDownLatchlatch; privatevolatilebooleanflag=true; privateObjectlock=newObject(); privateAtomicIntegernum=newAtomicInteger(0); classJobAimplementsRunnable{ @Override publicvoidrun(){ synchronized(lock){ flag=false; if(num.get()!=3){ try{ lock.wait();//wait方法会释放锁 }catch(InterruptedExceptione){ } } System.out.println("任务A收到通知,继续执行作业"); } latch.countDown(); } } classJobBimplementsRunnable{ @Override publicvoidrun(){ while(flag){//保证JobA先申请到锁 } synchronized(lock){ for(inti=1;i<=5;i++){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ } inta=num.incrementAndGet(); System.out.println("任务B第"+i+"次执行,num值为:"+a); if(a==3){ lock.notify();//唤醒JobB线程,notify方法不会释放锁 } } } latch.countDown(); } } @Test publicvoidtest(){ latch=newCountDownLatch(2); newThread(newJobA()).start(); newThread(newJobB()).start(); try{ latch.await();//保证2个线程都执行完毕 }catch(InterruptedExceptione){ } } }
结果输出:
任务B第1次执行,num值为:1
任务B第2次执行,num值为:2
任务B第3次执行,num值为:3
任务B第4次执行,num值为:4
任务B第5次执行,num值为:5
任务A收到通知,继续执行作业
示例二:
packagecom.zhi.test; importjava.util.concurrent.CountDownLatch; importjava.util.concurrent.locks.LockSupport; importorg.junit.Test; /** *Java多线程-线程通讯示例,利用LockSupport * *@author张远志 *@since2020年5月4日21:51:24 * */ publicclassThreadTest3{ privateCountDownLatchlatch; privatevolatileintnum=0; privateThreadta; privateThreadtb; classJobAimplementsRunnable{ @Override publicvoidrun(){ if(num!=3){ LockSupport.park(); } System.out.println("任务A收到通知,继续执行作业"); latch.countDown(); } } classJobBimplementsRunnable{ @Override publicvoidrun(){ for(inti=1;i<=5;i++){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ } num++; System.out.println("任务B第"+i+"次执行,num值为:"+num); if(num==3){ LockSupport.unpark(ta);//unpark会立即激活传入线程 } } latch.countDown(); } } @Test publicvoidtest(){ latch=newCountDownLatch(2); ta=newThread(newJobA()); tb=newThread(newJobB()); ta.start(); tb.start(); try{ latch.await();//保证2个线程都执行完毕 }catch(InterruptedExceptione){ } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。