方式一
方式二
方式二在每个线程中加入countDown,需保证一定执行,不然主线程会一直卡住。
例:
简历一个
@Slf4j
public class CountDownLatchRunnable implements Runnable {
private final String command;
private final CountDownLatch countDownLatch;
public CountDownLatchRunnable(String command, CountDownLatch countDownLatch) {
this.command = command;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
log.info(Thread.currentThread().getName() + " start. Command = " + command);
processCommand(command);
log.info(Thread.currentThread().getName() + " finish.");
}
private void processCommand(String command) {
log.info(Thread.currentThread().getName() + ":, doing work:" + command);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
}
}
- 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.
public class Run {
public static void main(String[] args) throws InterruptedException {
log.info("Main thread start.");
int theadNum = 3;
// CountDownLatch 需要将对象传入需要'等待完成'的线程对象中
CountDownLatch countDownLatch = new CountDownLatch(theadNum);
ExecutorService executorService = Executors.newFixedThreadPool(theadNum);
Runnable worker = new CountDownLatchRunnable("Task", countDownLatch);
// 创建5个线程, 提交到线程池
for (int i = 0; i < theadNum; i++) {
executorService.execute(worker); // 同一个实例对象
}
// 等待所有线程执行完成(线程阻塞)
countDownLatch.await();
log.info("Main thread finish.");
// 停止接受新任务,当已有任务将执行完,关闭线程池
executorService.shutdown();
// 等待线程池中所有的任务执行完成, 前提是执行了 shutdown
while (!executorService.isTerminated()) {
// 等待所有线程执行完成
}
log.info("exit");
}
}
- 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.