前段时间面试被问了一个问题:
“ABC三个线程,如何让AB并发执行完了再顺序执行C?”
“额,不好意思,不清楚唉,我自己回家等通知吧 = =”
再一次感慨过去写过的代码,业务场景不复杂,都没有很多对线程的操作,印象中使用过的就是Thread.sleep(),更不用说多线程了……唉,需要学习的东西还有很多啊,好好学习,天天向上~
以下两种实现方式文字部分摘抄整理自:日积月累:Java等待子线程执行完毕,再执行后续逻辑
1. Join
Thread提供了 join() 让一个线程等待另一个线程完成的方法。当在某个程序执行流程中调用其它线程的join()方法时,调用线程将被阻塞,知道被join()方法加入的join线程执行完毕为止,在继续运行。
join()方法的实现原理是不停检查join线程是否存活,如果join线程存活则让当前线程永远等待。直到join线程完成后,线程的this.notifyAll()方法会被调用。
代码如下:
public class Test1 {
public static void main (String[] args) {
Thread t1 = new Thread(new TestThread(), "threadA");
Thread t2 = new Thread(new TestThread(), "threadB");
t1.start();
t2.start();
try {
t1.join(); // 主线程等待A线程执行完
t2.join(); // 主线程等待B线程执行完
} catch (InterruptedException e) {
e.printStackTrace();
}
// 然后就可以愉快的执行C线程啦~
new Thread(new TestThread(), "threadC");
}
}
class TestThread implements Runnable {
@Override
public void run() {
for (int i = 0 ; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " am running: " + i);
}
}
}
2. CountDownLatch
CountDownLatch允许一个或多个线程等待其他线程完成操作。CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N。当我们调用countDown方法时,N就会减1,await方法会阻塞当前线程,直到N变成0。
这里说的N个点,可以使用N个线程,也可以是1个线程里的N个执行步骤。
/**
* Created by chenhuogu on 2018/7/24.
*/
public class Test1 {
public static void main (String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(2);
Thread t1 = new Thread(new TestThread(countDownLatch), "threadA");
Thread t2 = new Thread(new TestThread(countDownLatch), "threadB");
t1.start();
t2.start();
try {
countDownLatch.await(); // await方法阻塞当前主线程,直到countDownLatch计数器为0,即线程全部执行完
} catch (InterruptedException e) {
e.printStackTrace();
}
// 然后就可以愉快的执行C线程啦~~~
}
}
class TestThread implements Runnable {
private CountDownLatch countDownLatch;
public TestThread (CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
for (int i = 0 ; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " am running: " + i);
}
countDownLatch.countDown();
}
}