java 多线程 执行完后_多线程执行时,如果一个逻辑需要等若干个线程执行完成后再执行,怎么实现?...

"本文介绍了在Java中如何使用多线程提高处理效率,并通过实例展示了如何确保主线程在所有子线程执行完毕后再执行。文章详细讲解了使用`join()`方法和`CountDownLatch`类两种方式实现线程同步,确保"执行完成"的输出在所有子线程结束后。这两种方法都能有效地控制线程执行顺序,达到预期效果。"
摘要由CSDN通过智能技术生成

实际开发过程中,尤其是大型的业务系统中或批量处理系统中,我们通常会用到多线程来进行任务拆分,来提高系统的处理能力。当对业务不断拆分时,多线程各自任务之间也形成了错综复杂的关系。

我们常常遇到这样的情况,业务模块A 拆分成了 A1 、A2.....An个多线程,来提高处理速度,可是 Ak(1

我们先定义两个实现多线程任务:

任务1:

public classWorkA1 extendsThread {

@Overridepublic voidrun() {

System.out.println("WorkA1 开始执行");try{

Thread.sleep(2000);} catch(InterruptedException e) {

e.printStackTrace();}

System.out.println("WorkA1 结束执行");}

}

任务2:

public classWorkA2 extendsThread {

@Overridepublic voidrun() {

System.out.println("WorkA2 开始执行");try{

Thread.sleep(1800);} catch(InterruptedException e) {

e.printStackTrace();}

System.out.println("WorkA2 结束执行");}

}

主线程开始实现是这样的:

public classThreedClient {

public static voidmain(String[] args) {

System.out.println("准备开始执行任务");WorkA1 workA1 = newWorkA1();WorkA2 workA2 = newWorkA2();workA1.start();workA2.start();System.out.println("执行完成了。");}

}

执行结果是:

准备开始执行任务

执行完成了。

WorkA1 开始执行

WorkA2 开始执行

WorkA2 结束执行

WorkA1 结束执行

如果我们想最后打印 “执行完成了”在所有子线程完成后,怎么办呢?

我们对主线程进行改造:

改造方法1:

public classThreedClient {

public static voidmain(String[] args) {

System.out.println("准备开始执行任务");WorkA1 workA1 = newWorkA1();WorkA2 workA2 = newWorkA2();workA1.start();workA2.start();try{

workA1.join();workA2.join();}catch(InterruptedException e){

e.printStackTrace();}

System.out.println("执行完成了。");}

}

改造完成后,在看执行结果:

准备开始执行任务

WorkA2 开始执行

WorkA1 开始执行

WorkA2 结束执行

WorkA1 结束执行

执行完成了。

OK,达到我们的预期了。

改造方法2:

CountDownLatch允许一个或多个线程等待其他线程完成操作。CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N。当我们调用countDown方法时,N就会减1,await方法会阻塞当前线程,直到N变成0。

它的原理很简单,就是你需要等待几个任务时,就先定义好,然后任务执行完成一个,计数器减1。看看具体实现:

public classWorkA1 extendsThread {

privateCountDownLatch countDownLatch;publicWorkA1(CountDownLatch countDownLatch) {

this.countDownLatch= countDownLatch;}

@Overridepublic voidrun() {

System.out.println("WorkA1 开始执行");try{

Thread.sleep(2000);} catch(InterruptedException e) {

e.printStackTrace();}finally{

countDownLatch.countDown();}

System.out.println("WorkA1 结束执行");}

}

Work2的改造跟Work1完全一样,就不再单独贴代码了。

看下主线程中的改造:

public classThreedClient {

public static voidmain(String[] args) {

System.out.println("准备开始执行任务");CountDownLatch countDownLatch = newCountDownLatch(2);WorkA1 workA1 = newWorkA1(countDownLatch);WorkA2 workA2 = newWorkA2(countDownLatch);workA1.start();workA2.start();try{

countDownLatch.await();}catch(InterruptedException e){

e.printStackTrace();}

System.out.println("执行完成了。");}

}

我们看下改造后的执行结果:

准备开始执行任务

WorkA1 开始执行

WorkA2 开始执行

WorkA2 结束执行

WorkA1 结束执行

执行完成了。

跟改造1中的效果一模一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值