java 线程 thread.join_java线程基础巩固---分析Thread的join方法详细介绍,结合一个典型案例...

关于Thread中的join方法貌似在实际多线程编程当中没怎么用过,在当初学j2se的时候倒时去学习过它的用法,不过现在早已经忘得差不多啦,所以对它再复习复习下。

首先先观察下JDK对它的介绍:

d44bb0b1504199b3490c366a93b46dee.png

其实就是等待一个线程结束,对它记忆中还是有印象的,下面实践一下:

366e7b306a84c5b9ee45ae40c4c87c20.png

这时很显然打印是交替进行的:

19999521f6d87781896c7fbb05264dad.png

那如果我们想让子线程执行完了之后再执行主线程呢?这时就可以用join来实现啦,如下:

a7fb42007f2176c1757411c6e7f9a026.png

这时结果就是先输出子线程的,然后再输出主线程的了,那join的主要作用就是会等待线程执行完,另外需要注意:join()必须是在start()之后:

72971f3f9e11bff0629a6e4e7c9efe93.png

接下来对其代码进行修改:

31429e9175c1171bfba6e330d386ae8b.png

那t1和t2打印结果会是顺序的么,也就是只有t1打印完了才会打印t2?看结果:

61f7e29e7b8b7e746111592aed08021d.png

很显然是并行交替执行的,但main线程是在等t1和t2线程结束之后再执行的么?这个应该比较容易猜到,当然是啦:

b77156b56051a646d2a4ea8549fc7f43.png

接下来用一下join()的另外两个重载:

28afff1188596542c75886a3e74e3a33.png

这时编译运行:

a5267ebd8aab444fd82da3f36e078d0d.gif

可以看到只等了100ms程序就开始往下执行main线程了,并且当子线程过了10s之后程序才退出,当然也可以给join传入一个ns:

7d1b358a8835c725061324b04a829d6f.png

具体就不运行了,这里看下面这种写法:

d7f0a425c92bf1dab6a67b3178ed3909.png

那运行之后会怎样?

3a69d6a3f78256e58839d58a53690563.png

这是由于join()在等main线程退出,但是main线程又由于这句话永远退不出,所以就死循环了,这个在有些场合会用得到,先对这种写法有个大致的印象。

接下来通过一个小案例进一步来体会下join的用法:就是分别采集不同服务器的数据,而每台服务器数据的采集由一个单独的线程进行处理,每采集一条数据则需要将这数据进行入库,其中统计总数据采集的开始时间与结束时间,下面用代码来模拟下:

public classThreadJoin3 {public static void main(String[] args) throwsInterruptedException {long startTime =System.currentTimeMillis();

Thread t1= new Thread(new CaptureRunnable("M1", 5000L));

Thread t2= new Thread(new CaptureRunnable("M2", 7000L));

Thread t3= new Thread(new CaptureRunnable("M3", 10000L));

t1.start();

t2.start();

t3.start();long endTime =System.currentTimeMillis();

System.out.printf("Save data begin time is:%s, end time is:%s\n", startTime, endTime);

}

}/*** 采集数据的业务代码*/

class CaptureRunnable implementsRunnable {/*采集的机器名*/

privateString machineName;/*采取花费的时间,直接由外部传过来模拟了*/

private longspendTime;public CaptureRunnable(String machineName, longspendTime) {this.machineName =machineName;this.spendTime =spendTime;

}

@Overridepublic voidrun() {//do the really capture data;

try{

Thread.sleep(spendTime);

System.out.printf(machineName+ " completed data capture at time [%s] and successfully.\n", System.currentTimeMillis());

}catch(InterruptedException e) {

e.printStackTrace();

}

}publicString getResult() {return machineName + " finish.";

}

}

编译运行:

b8bf6a43239f555ce2dddc5f0e8d8947.gif

呃~~还没运行完其统计的开始时间与结束时间就已经提前打印出来了,那不是我们期望的,这时join()就可以很好的解决这个问题啦,修改代码如下:

4f3ae24ef18d83974c60e884ff803b47.png

编译运行:

24f0096dd6bc8226710aa109392fde32.gif

嗯~~完美解决~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值