介绍

对线程的等待机制进行优化,还是同样的例子

前几天我去买正新鸡排,买一个鸡排送一杯饮料,在炸鸡排的同时,可以调制装配饮料,因此,可以将这两个操作并行,当两个操作执行完,进行包装完成售出

如果有多个人进行购买,那么以上操作就有了优化的空间。可以使用线程池将线程的重复创建优化掉。但是为了减少重复创建,就要保证线程不销毁,那么就无法使用 join() 来完成,因此引入了新的等待机制 CountDownLatch 与 CyclicBarrier。这个等待机制的原理就是利用计数器,给计数器设置一个初始值,每完成一个等待操作,计数器值就-1,当计数器值为0时,等待结束,继续执行。CountDownLatch 与 CyclicBarrier不同的是,当计数器值为0时,如果需要继续这个等待行为,CountDownLatch 需要手动重新设置计数器初始值,而 CyclicBarrier 则是当计数器值为0时,调用处理机制,然后重新将计数器值恢复为初始值

使用

  1. package cn.zjm404.stu.thread.cooperation.wait.pool;
  2. import java.util.concurrent.*;
  3. public class ZhengXinChickenChopShop {
  4. private ThreadPoolExecutor tp;
  5. public ZhengXinChickenChopShop(ThreadPoolExecutor tp){
  6. this.tp = tp;
  7. }
  8. private void getDrink(){
  9. System.out.println("配置饮料");
  10. }
  11. private void getChickenChop(){
  12. System.out.println("炸鸡排");
  13. }
  14. /**
  15. * 使用 CountDownLatch
  16. */
  17. public void sellChickenChop1(){
  18. CountDownLatch ctl = new CountDownLatch(2);
  19. tp.execute(()->{
  20. getDrink();
  21. ctl.countDown();
  22. });
  23. tp.execute(()->{
  24. getChickenChop();
  25. ctl.countDown();
  26. });
  27. try {
  28. ctl.await();
  29. } catch (InterruptedException e) {
  30. Thread.currentThread().isInterrupted();
  31. e.printStackTrace();
  32. }
  33. System.out.println("打包,售出");
  34. }
  35. /**
  36. * 使用 CyclicBarrier
  37. */
  38. public void sellChickenChop2(){
  39. CyclicBarrier cb = new CyclicBarrier(2,()->{
  40. System.out.println("打包,售出");
  41. });
  42. tp.execute(()->{
  43. getDrink();
  44. try {
  45. cb.await();
  46. } catch (InterruptedException e) {
  47. e.printStackTrace();
  48. } catch (BrokenBarrierException e) {
  49. e.printStackTrace();
  50. }
  51. });
  52. tp.execute(()->{
  53. getChickenChop();
  54. try {
  55. cb.await();
  56. } catch (InterruptedException e) {
  57. e.printStackTrace();
  58. } catch (BrokenBarrierException e) {
  59. e.printStackTrace();
  60. }
  61. });
  62. }
  63. }
  1. public class Client {
  2. public static void main(String[] args){
  3. ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
  4. ZhengXinChickenChopShop shop = new ZhengXinChickenChopShop(poolExecutor);
  5. shop.sellChickenChop2();
  6. poolExecutor.shutdown();
  7. }
  8. }

image.png

参考