1 案例介绍

在日常开发中经常会遇到需要在主线程中开启多 线程去并行执行任务 并且主线程需要等待所有子线程执行完 后再进行汇总的场景。在 CountDownL tch 出现之前一般都使用线程的 join () 方法来实现这一点,但是 join 方法不够灵活 不能够满足不同场景的需要,所以 JDK 开发组提供了 ountDo nLatch 这个类。

demo1:

  1. public class CountDownLatchTest {
  2. public static void main(String[] args) throws InterruptedException {
  3. CountDownLatch latch = new CountDownLatch(5);
  4. ConcurrentHashMap cMap = new ConcurrentHashMap();
  5. for (int i = 0; i < 5; i++) {
  6. int finalI = i;
  7. Thread t = new Thread(new Runnable() {
  8. @Override
  9. public void run() {
  10. cMap.put("key" + finalI, finalI);
  11. System.out.println(finalI);
  12. latch.countDown();
  13. System.out.println("latch.getCount():"+latch.getCount());
  14. }
  15. });
  16. t.start();
  17. }
  18. latch.await();
  19. System.out.println("最后latch.getCount():"+latch.getCount());
  20. System.out.println("map大小:" + cMap.size());
  21. }
  22. }

输出:

  1. 0
  2. latch.getCount():4
  3. 1
  4. latch.getCount():3
  5. 2
  6. latch.getCount():2
  7. 4
  8. latch.getCount():1
  9. 3
  10. latch.getCount():0
  11. 最后latch.getCount():0
  12. map大小:5

demo2:

  1. public class CountDownLatchTest2 {
  2. public static void main(String[] args) throws InterruptedException {
  3. CountDownLatch latch = new CountDownLatch(2);
  4. Thread t = new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. try {
  8. System.out.println("子线程sleep 5s");
  9. Thread.sleep(5000);
  10. System.out.println("子线程运行结束");
  11. latch.countDown();
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. });
  17. Thread t2 = new Thread(new Runnable() {
  18. @Override
  19. public void run() {
  20. try {
  21. System.out.println("子线程2 sleep 3s");
  22. Thread.sleep(3000);
  23. System.out.println("子线程2运行结束");
  24. latch.countDown();
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. });
  30. Thread mainThtead = new Thread(new Runnable() {
  31. @Override
  32. public void run() {
  33. try {
  34. System.out.println("主线程sleep 1s");
  35. Thread.sleep(1000);
  36. System.out.println("主线程运行结束");
  37. } catch (InterruptedException e) {
  38. e.printStackTrace();
  39. }
  40. System.out.println("这是一个主线程,todo...");
  41. }
  42. });
  43. t.start();
  44. t2.start();
  45. latch.await();
  46. mainThtead.start();
  47. }
  48. }

输出:

  1. 子线程sleep 5s
  2. 子线程2 sleep 3s
  3. 子线程2运行结束
  4. 子线程运行结束
  5. 主线程sleep 1s
  6. 主线程运行结束
  7. 这是一个主线程,todo...

注释掉CountDownLatch输出:

  1. 子线程2 sleep 3s
  2. 主线程运行结束
  3. 这是一个主线程,todo...
  4. 子线程2运行结束
  5. 子线程运行结束