多线程顺序执行,只知道两种?
故事
上周一位同学在面试中遇到了这么一道问题:
有三个线程T1、T2、T3,如何保证顺序执行?
常规操作,启动三个线程,让其执行。
public class ThreadDemo { public static void main(String[] args) { final Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("线程1"); } }); final Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("线程2"); } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { System.out.println("线程3"); } }); t1.start(); t2.start(); t3.start(); } }登录后复制
线程2 线程1 线程3登录后复制
怎么办呢?下面我们使用四种方案来实现。
方案一
我们可以利用Thread中的join方法解决线程顺序问题,下面我们来简单介绍一下join方法。
官方介绍:
Waits for this thread to die.
等待这个线程结束,也就是说当前线程等待这个线程结束后再继续执行 。
join()
方法是Thread
中的一个public
方法,它有几个重载版本:
join()
join(long millis)
//参数为毫秒join(long millis,int nanoseconds)
//第一参数为毫秒,第二个参数为纳秒
join()方法实际是利用了wait()
方法(wait方法是Object中的),只不过它不用等待notify()/notifyAll()
,且不受其影响。
它结束的条件是:
- 等待时间到
- 目标线程已经run完(通过
isAlive()
方法来判断)
下面大致看看器源码:
public final void join() throws InterruptedException { //调用了另外一个有参数的join方法 join(0); } public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis t2.start()) .thenRun(()->t3.start()); } static class Work implements Runnable{ @Override public void run() { System.out.println("执行 : " + Thread.currentThread().getName()); } } }登录后复制
执行 : 线程1 执行 : 线程2 执行 : 线程3登录后复制
总结
关于多个线程顺序执行,不管是对于面试,还是工作,关于多线程顺序执行的解决方案都是非常有必要掌握的。也希望下次面试官再问:多线程顺序执行问题的时候,你的表情应该是这样的: