在执行前面所有的线程后再执行后续逻辑
代码如下:
WorkThread.java
public class WorkThread extends Thread {
@Override
public void run() {
try {
System.out.println(getName() + "run start.");
//模拟完成子任务执行的时间
sleep(1000);
System.out.println(getName() + "run finished.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
//启动两个子线程执行子任务
WorkThread workThread1 = new WorkThread();
WorkThread workThread2 = new WorkThread();
workThread1.start();
workThread2.start();
//运行后面的业务
System.out.println("run next process.");
}
}
运行结果如下,在子线程启动后,Main线程就继续执行后面的逻辑,并不能满足我们的业务场景:
AppMain Main
run next process.
Thread-0run start.
Thread-1run start.
Thread-1run finished.
Thread-0run finished.
那么,我们有如下几种方式,可以实现以上的业务场景。
一、Join
Thread提供了让一个线程等待另一个线程完成的方法—join()方法。当在某个程序执行流程中调用其它线程的join()方法时,调用线程将被阻塞,知道被join()方法加入的join线程执行完毕为止,在继续运行。
join()方法的实现原理是不停检查join线程是否存活,如果join线程存活则让当前线程永远等待。直到join线程完成后,线程的this.notifyAll()方法会被调用。
修改Main.java如下:
public class Main {
public static void main(String[] args) {
WorkThread workThread1 = new WorkThread();
WorkThread workThread2 = new WorkThread();
workThread1.start();
workThread2.start();
//阻塞Main线程,执行子线程workThread1和workThread2,完毕后继续执行后续的逻辑
try {
workThread1.join();
workThread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run next process.");
}
}
运行结果如下:
Thread-0run start.
Thread-1run start.
Thread-0run finished.
Thread-1run finished.
run next process.
二、CountDownLatch
CountDownLatch允许一个或多个线程等待其他线程完成操作。CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N。当我们调用countDown方法时,N就会减1,await方法会阻塞当前线程,直到N变成0。
这里说的N个点,可以使用N个线程,也可以是1个线程里的N个执行步骤。
修改WorkThread.java和Main.java如下:
WorkThread.java
public class WorkThread extends Thread {
private CountDownLatch countDownLatch;
public WorkThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
System.out.println(getName() + "run start.");
sleep(1000);
//执行子任务完毕之后,countDown减少一个点
countDownLatch.countDown();
System.out.println(getName() + "run finished.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
//创建2个点的CountDownLatch对象
CountDownLatch countDownLatch = new CountDownLatch(2);
//将countDownLatch对象的引用传递给子线程里
WorkThread workThread1 = new WorkThread(countDownLatch);
WorkThread workThread2 = new WorkThread(countDownLatch);
workThread1.start();
workThread2.start();
try {
//调用await方法阻塞当前线程,等待子线程完成后在继续执行
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run next process.");
}
}
运行结果如下:
Thread-0run start.
Thread-1run start.
Thread-0run finished.
Thread-1run finished.
run next process.
原文:https://blog.csdn.net/p106786860/article/details/52497215