控制并发流程 - 图1

代码演示

CountDownLautch

  1. // 等待线程数量
  2. int size = 10;
  3. // 倒计时数量
  4. int count = 2;
  5. Thread[] waitThreads = new Thread[size];
  6. Thread decrThread;
  7. CountDownLatch countDownLatch = new CountDownLatch(count);
  8. Runnable r = () -> {
  9. try {
  10. System.out.println(Thread.currentThread().getName() + "开始等待");
  11. // 调用 await(),会让线程等待
  12. countDownLatch.await();
  13. System.out.println(Thread.currentThread().getName() + "等待完毕");
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. };
  18. for (int i = 0; i < size; i++) {
  19. waitThreads[i] = new Thread(r);
  20. }
  21. decrThread = new Thread(() -> {
  22. for (; countDownLatch.getCount() != 0; ) {
  23. try {
  24. TimeUnit.SECONDS.sleep(1);
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. } finally {
  28. // count 减一操作
  29. countDownLatch.countDown();
  30. }
  31. }
  32. });
  33. // 线程开始等待
  34. for (int i = 0; i < size; i++) {
  35. waitThreads[i].start();
  36. }
  37. // 减 count 线程启动
  38. decrThread.start();
  39. TimeUnit.SECONDS.sleep(10);
  1. Thread-0开始等待
  2. Thread-3开始等待
  3. Thread-2开始等待
  4. Thread-1开始等待
  5. Thread-4开始等待
  6. Thread-5开始等待
  7. Thread-6开始等待
  8. Thread-7开始等待
  9. Thread-8开始等待
  10. Thread-9开始等待
  11. Thread-3等待完毕
  12. Thread-5等待完毕
  13. Thread-6等待完毕
  14. Thread-8等待完毕
  15. Thread-9等待完毕
  16. Thread-4等待完毕
  17. Thread-1等待完毕
  18. Thread-2等待完毕
  19. Thread-0等待完毕
  20. Thread-7等待完毕

Semaphore

  1. ExecutorService service = Executors.newFixedThreadPool(10);
  2. // 指定信号量数量
  3. int count = 5;
  4. Semaphore semaphore = new Semaphore(count);
  5. Runnable runnable = () -> {
  6. try {
  7. System.out.println(Thread.currentThread().getName() + " 尝试获取许可证");
  8. // 尝试获取许可证,拿不到会 blocking
  9. semaphore.acquire();
  10. System.out.println(Thread.currentThread().getName() + " start working");
  11. TimeUnit.SECONDS.sleep(new Random().nextInt(5));
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. } finally {
  15. // 绝对要归还许可证
  16. semaphore.release();
  17. System.out.println(Thread.currentThread().getName() + " 归还许可证");
  18. }
  19. };
  20. for (int i = 0; i < 10; i++) {
  21. service.submit(runnable);
  22. }
  23. service.shutdown();
  24. while (!service.isTerminated());
  1. pool-1-thread-2 尝试获取许可证
  2. pool-1-thread-2 start working
  3. pool-1-thread-1 尝试获取许可证
  4. pool-1-thread-1 start working
  5. pool-1-thread-3 尝试获取许可证
  6. pool-1-thread-3 start working
  7. pool-1-thread-4 尝试获取许可证
  8. pool-1-thread-4 start working
  9. pool-1-thread-4 归还许可证
  10. pool-1-thread-5 尝试获取许可证
  11. pool-1-thread-5 start working
  12. pool-1-thread-6 尝试获取许可证
  13. pool-1-thread-6 start working
  14. pool-1-thread-6 归还许可证
  15. pool-1-thread-7 尝试获取许可证
  16. pool-1-thread-7 start working
  17. pool-1-thread-8 尝试获取许可证
  18. pool-1-thread-9 尝试获取许可证
  19. pool-1-thread-10 尝试获取许可证
  20. pool-1-thread-8 start working
  21. pool-1-thread-2 归还许可证
  22. pool-1-thread-9 start working
  23. pool-1-thread-8 归还许可证
  24. pool-1-thread-1 归还许可证
  25. pool-1-thread-10 start working
  26. pool-1-thread-10 归还许可证
  27. pool-1-thread-3 归还许可证
  28. pool-1-thread-5 归还许可证
  29. pool-1-thread-7 归还许可证
  30. pool-1-thread-9 归还许可证

第一层密码:CKNB 第二层密码:HRLM