首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java多线程join方法

前言

有次偶尔接触到了Thread.join()方法,便到网上去查阅相关资料,但也是看得我一头雾水(天下文章一般抄)。在我很久的理解之后,便想将我理解的join()方法以一张图的方式解释出来。

要学习本篇文章,你需要理解以下知识:

仔细看

开局扔张图:

我绘制的这张图以时间线的形式解释了主线程和各个被实例化的John线程的运行过程。

别着急,多看两遍!

我们可以看到,在主线程调用了join()方法后,指定的线程会被抓回来在后边老老实实地排队。

猜一下

问:请回答未执行join()方法和执行了join()方法的运行结果有什么不同(可能有几种结果、运行的时间、输出的顺序)?

答:

类型|可能结果数量|运行速度|输出顺序|时间复杂度(最好)

---|---|---

不使用join()|6种|快(多线程)|乱序|O(1)

使用join()|1种|慢(单线程)|顺序|O(n)

Q&A

看完后,你可能还会有些疑问:

Q:为什么不使用join()的可能结果数量是6种?输出顺序为什么是乱序?

A:由于多线程的原因,虽然start()顺序执行了线程1/2/3,但可能由于各种原因,某个线程会抢先完成,从而造成了6种运行结果 ——

多线程并不老实,并且难以(不是不可能)控制。

Q:为什么使用join()后会变慢?

A:因为使用join()后,三个线程会按顺序被赶到主线程去运行,这时候它们就不能够同时运行了,只能一个一个地运行。

自己做

别偷懒,打开你的IDE,把下边的代码粘贴进去:

1public class TestJoin {

2 public static void main(String[] args) {

3 John john1 = new John();

4 John john2 = new John();

5 John john3 = new John();

6

7 try {

8 john1.start();

9 john1.join();

10 john2.start();

11 john2.join();

12 john3.start();

13 john3.join();

14 } catch (InterruptedException IE) {

15 IE.printStackTrace();

16 }

17 }

18}

19

20class John extends Thread {

21 @Override

22 public void run() {

23 for (int i = 0; i < 2; i++)

24 {

25 try

26 {

27 Thread.sleep(500);

28 System.out.println("Current Thread: "

29 + Thread.currentThread().getName());

30 }

31

32 catch(Exception ex)

33 {

34 System.out.println("Exception has" +

35 " been caught" + ex);

36 }

37 System.out.println(i);

38 }

39 }

40}

41

运行结果:

1Current Thread: Thread-0

20

3Current Thread: Thread-0

41

5Current Thread: Thread-1

60

7Current Thread: Thread-1

81

9Current Thread: Thread-2

100

11Current Thread: Thread-2

121

可以看到,苦逼的三个线程都被拉到了主线程顺序执行。

现在,删掉两行代码:

1john2.join();

2john3.join();

再次运行:

1Current Thread: Thread-0

20

3Current Thread: Thread-0

41

5Current Thread: Thread-1

60

7Current Thread: Thread-2

80

9Current Thread: Thread-2

101

11Current Thread: Thread-1

121

可以看到,john2和john3两个线程并未在主线程中运行,所以运行结果也发挥得比较自由,且运行时间也缩短了。

此处请注意,在使用join()方法之前,一定要先使用start()方法启动线程。线程根本没工作,那还咋拉过去?

后语

到此,你已经掌握了join()方法的使用。不要问我能用来做什么,等到你需要它的功能时,你就不会再手忙脚乱了。

很认真,你读到了最后。让我们再来讲讲yield()方法吧(别的文章都讲了):

yield()方法的作用,与join()方法无瓜。当你对一个线程执行yield()方法后,该线程会尝试暂停自己,给后面正在排队的同级线程让道(即拱手让人),它是一个不稳定的过程(不一定有效果,也不一定什么时候继续执行)。

另外,建议你趁着还能再学进点什么,再看看syncronized、wait()、notify()这些有相似之处的知识比较好。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/Ohzbe8BYOhOpPxSSNj6ANkrg0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券