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){
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。