CountDownLatch用于主线程和子线程协同配合,常用2种使用方式:
- 主线程等待所有的子线程完成任务后再执行
- 所有的子线程准备,等待主线程发令执行
用法一:主线程等子线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| private static void m2() throws InterruptedException { CountDownLatch countDownLatch2 = new CountDownLatch(5); for (int i = 0; i < 5; i++) { new Thread(() -> { try { String name = Thread.currentThread().getName(); System.out.println("子线程"+name+"执行任务中..."); Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(2000)); System.out.println("子线程"+name+"完成任务"); countDownLatch2.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } System.out.println("主线程等待中...."); countDownLatch2.await(); System.out.println("主线程:在所有任务运行完成后,进行结果汇总"); }
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12
| 子线程Thread-0执行任务中... 子线程Thread-2执行任务中... 主线程等待中.... 子线程Thread-1执行任务中... 子线程Thread-3执行任务中... 子线程Thread-4执行任务中... 子线程Thread-1完成任务 子线程Thread-0完成任务 子线程Thread-3完成任务 子线程Thread-2完成任务 子线程Thread-4完成任务 主线程:在所有任务运行完成后,进行结果汇总
|
用法二:所有子线程准备,等待主线程发令执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| CountDownLatch countDownLatch = new CountDownLatch(1); for (int i = 0; i < 5; i++) { new Thread(() -> { try { countDownLatch.await(); String parter = "【" + Thread.currentThread().getName() + "】"; System.out.println(parter + "开始执行……"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); System.out.println("创建线程时间:"+LocalDateTime.now()); }
System.out.println("裁判准备发令"); System.out.println("3"); Thread.sleep(1000); System.out.println("2"); Thread.sleep(1000); System.out.println("1"); Thread.sleep(1000); countDownLatch.countDown();
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 创建线程时间:2022-03-06T19:12:55.077911700 创建线程时间:2022-03-06T19:12:55.077911700 创建线程时间:2022-03-06T19:12:55.077911700 创建线程时间:2022-03-06T19:12:55.077911700 创建线程时间:2022-03-06T19:12:55.077911700 裁判准备发令 3 2 1 【Thread-0】开始执行…… 【Thread-2】开始执行…… 【Thread-4】开始执行…… 【Thread-1】开始执行…… 【Thread-3】开始执行……
|
ps:
- CountDownLatch的作用就是允许一个或多个线程等待其他线程完成操作,看起来有点类似join()方法,但其提供了比join()更加灵活的API。
- CountDownLatch可以手动控制在n个线程里调用n次countDown()方法使计数器进行减一操作,也可以在一个线程里调用n次执行减一操作。
- Thread.join() 当我们调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行。