查看: 490|回复: 0

[Java学习] java并发编程之CyclicBarrier

发表于 2017-1-6 12:00:02
句号论坛
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。


CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。

CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。 CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。

这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。

  1. package com.lala.shop;
  2. import java.util.Random;
  3. import java.util.concurrent.BrokenBarrierException;
  4. import java.util.concurrent.CyclicBarrier;
  5. import java.util.concurrent.ExecutorService;
  6. import java.util.concurrent.Executors;
  7. import java.util.concurrent.TimeUnit;
  8. /**
  9. * 这里演示了一个例子:五个人一同去买 衬衫、裤子、鞋子。
  10. * 所有人必须先全部买完衬衫,然后才能去买裤子,全部买完裤子之后,在去买鞋子,全部买完鞋子之后,事情执行完成
  11. */
  12. public class CyclicBarrierDemo
  13. {
  14. public static void main(String[] args)
  15. {
  16. CyclicBarrier cb = new CyclicBarrier(5, new Runnable(){
  17. public void run()
  18. {
  19. System.out.println("人已经到齐,准备下一步...");
  20. }
  21. });
  22. ExecutorService runner = Executors.newFixedThreadPool(5);
  23. runner.submit(new Shopping("李大嘴", cb));
  24. runner.submit(new Shopping("白展堂", cb));
  25. runner.submit(new Shopping("郭芙蓉", cb));
  26. runner.submit(new Shopping("佟湘玉", cb));
  27. runner.submit(new Shopping("吕秀才", cb));
  28. runner.shutdown();
  29. }
  30. }
  31. class Shopping implements Runnable
  32. {
  33. private String user;
  34. private CyclicBarrier cb;
  35. public Shopping(String user, CyclicBarrier cb)
  36. {
  37. this.user = user;
  38. this.cb = cb;
  39. }
  40. public void run()
  41. {
  42. try
  43. {
  44. long shirtTime = getRandomTime();
  45. TimeUnit.SECONDS.sleep(shirtTime);
  46. System.out.println(user + "买完衬衫,花了时间:" + shirtTime);
  47. cb.await();
  48. long pantsTime = getRandomTime();
  49. TimeUnit.SECONDS.sleep(pantsTime);
  50. System.out.println(user + "买完裤子,花了时间:" + pantsTime);
  51. cb.await();
  52. long shoseTime = getRandomTime();
  53. TimeUnit.SECONDS.sleep(shoseTime);
  54. System.out.println(user + "买完鞋子,花了时间:" + shoseTime);
  55. cb.await();
  56. System.out.println(user + "东西已经买齐了,回家");
  57. } catch (InterruptedException | BrokenBarrierException e)
  58. {
  59. e.printStackTrace();
  60. }
  61. }
  62. private long getRandomTime()
  63. {
  64. return new Random().nextInt(9) + 1;
  65. }
  66. }
复制代码

输出结果为:


吕秀才买完衬衫,花了时间:1
白展堂买完衬衫,花了时间:1
佟湘玉买完衬衫,花了时间:3
李大嘴买完衬衫,花了时间:8
郭芙蓉买完衬衫,花了时间:9
人已经到齐,准备下一步...
白展堂买完裤子,花了时间:4
佟湘玉买完裤子,花了时间:4
吕秀才买完裤子,花了时间:5
郭芙蓉买完裤子,花了时间:8
李大嘴买完裤子,花了时间:9
人已经到齐,准备下一步...
吕秀才买完鞋子,花了时间:1
白展堂买完鞋子,花了时间:2
佟湘玉买完鞋子,花了时间:7
郭芙蓉买完鞋子,花了时间:8
李大嘴买完鞋子,花了时间:8
人已经到齐,准备下一步...
李大嘴东西已经买齐了,回家
吕秀才东西已经买齐了,回家
白展堂东西已经买齐了,回家
郭芙蓉东西已经买齐了,回家
佟湘玉东西已经买齐了,回家


回复

使用道具 举报

关闭

站长推荐上一条 /1 下一条