文章介绍4种方法,简单易懂,通过4个demo抛砖引玉。
在子线程中通过join()方法指定顺序
通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行。举例:在线程thread2中,加上一句thread1.join(),其意义在于,当前线程2运行到此行代码时会进入阻塞状态,直到线程thread1执行完毕后,线程thread2才会继续运行,这就保证了线程thread1与线程thread2的运行顺序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public class ThreadJoinDemo { public static void main(String[] args) throws InterruptedException { final Thread thread1 = new Thread( new Runnable() { @Override public void run() { System.out.println( "打开冰箱!" ); } }); final Thread thread2 = new Thread( new Runnable() { @Override public void run() { try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( "拿出一瓶牛奶!" ); } }); final Thread thread3 = new Thread( new Runnable() { @Override public void run() { try { thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( "关上冰箱!" ); } }); //下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经指定了运行顺序。 thread3.start(); thread2.start(); thread1.start(); } } |
运行结果:
打开冰箱!
拿出一瓶牛奶!
关上冰箱!
在主线程中通过join()方法指定顺序
简单说一下子线程与主线程的区别,子线程指的是发生在Thread内部的代码,主线程指的是发生在main函数中的代码,我们可以在main函数中通过join()方法让主线程阻塞等待以达到指定顺序执行的目的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class ThreadMainJoinDemo { public static void main(String[] args) throws InterruptedException { final Thread thread1 = new Thread( new Runnable() { @Override public void run() { System.out.println( "打开冰箱!" ); } }); final Thread thread2 = new Thread( new Runnable() { @Override public void run() { System.out.println( "拿出一瓶牛奶!" ); } }); final Thread thread3 = new Thread( new Runnable() { @Override public void run() { System.out.println( "关上冰箱!" ); } }); thread1.start(); thread1.join(); thread2.start(); thread2.join(); thread3.start(); } } |
输出结果:
打开冰箱!
拿出一瓶牛奶!
关上冰箱!
通过倒数计时器CountDownLatch实现
CountDownLatch通过计数器提供了更灵活的控制,只要检测到计数器为0当前线程就可以往下执行而不用管相应的thread是否执行完毕。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
public class ThreadCountDownLatchDemo { private static CountDownLatch countDownLatch1 = new CountDownLatch( 1 ); private static CountDownLatch countDownLatch2 = new CountDownLatch( 1 ); public static void main(String[] args) { final Thread thread1 = new Thread( new Runnable() { @Override public void run() { System.out.println( "打开冰箱!" ); countDownLatch1.countDown(); } }); final Thread thread2 = new Thread( new Runnable() { @Override public void run() { try { countDownLatch1.await(); System.out.println( "拿出一瓶牛奶!" ); countDownLatch2.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }); final Thread thread3 = new Thread( new Runnable() { @Override public void run() { try { countDownLatch2.await(); System.out.println( "关上冰箱!" ); } catch (InterruptedException e) { e.printStackTrace(); } } }); //下面三行代码顺序可随意调整,程序运行结果不受影响 thread3.start(); thread1.start(); thread2.start(); } } |
输出结果:
打开冰箱!
拿出一瓶牛奶!
关上冰箱!
通过创建单一化线程池newSingleThreadExecutor()实现
单线程化线程池(newSingleThreadExecutor)的优点,串行执行所有任务。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class ThreadPoolDemo { static ExecutorService executorService = Executors.newSingleThreadExecutor(); public static void main(String[] args) { final Thread thread1 = new Thread( new Runnable() { @Override public void run() { System.out.println( "打开冰箱!" ); } }); final Thread thread2 = new Thread( new Runnable() { @Override public void run() { System.out.println( "拿出一瓶牛奶!" ); } }); final Thread thread3 = new Thread( new Runnable() { @Override public void run() { System.out.println( "关上冰箱!" ); } }); executorService.submit(thread1); executorService.submit(thread2); executorService.submit(thread3); executorService.shutdown(); //使用完毕记得关闭线程池 } } |
输出结果:
打开冰箱!
拿出一瓶牛奶!
关上冰箱!
到此这篇关于Java让多线程按顺序执行的几种方法的文章就介绍到这了,更多相关Java多线程按顺序执行内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/jqc874789596/article/details/100557300