简单使用CyclicBarrier(栏栅)

阅读: 评论:0

简单使用CyclicBarrier(栏栅)

简单使用CyclicBarrier(栏栅)

1.需求分析
使用CyclicBarrier类模拟赛跑功能:新建N个人选手,当所有选手准备好时,开始前进一次,每次前进的距离随机在1-3之间,所有选手前进一次后,裁判开始检查有没有到达终点的选手,没有则继续之前操作,直到有一人或多人同时到达终点。
2.Person类
public class Person extends Thread{private final String name;private CyclicBarrier cb;//本次前进之后的总距离private int now;public Person(String name,CyclicBarrier cb){this.name = name;this.cb = cb;}public synchronized int getNow(){return now;}public synchronized String getPersonName(){return name;}@Overridepublic void run(){while(true){try {cb.await();int random = (int)(Math.random()*3+1);synchronized (this) {now += random;System.out.println(name +"本次跑了 "+random+" 米,共跑了 "+now+" 米");}} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}} }
3.Judge类
public class Judge extends Thread{private static final int MAX = 100;private CopyOnWriteArrayList<Person> cowl; public synchronized void setCowl(CopyOnWriteArrayList<Person> cowl){wl = cowl;}private void judge(){System.out.println("n==============start judge=================");/*try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}*/List<Person> list  = new ArrayList<>();for(Person p :cowl){Now()>=MAX)list.add(p);}if(list.size()!=0){for(Person p:list)System.out.PersonName()+"率先抵达终点!");it(0);}System.out.println("n==============end judge=================");}@Overridepublic void run() {judge();}
}
4.测试启动类
public class CyclicBarrierTest {public static void main(String[] args) {Judge judge = new Judge();CyclicBarrier cb = new CyclicBarrier(10, judge);List<Person> list = new ArrayList<>();for(int i=0;i<10;i++){Person p = new Person("tom"+i,cb);p.start();list.add(p);}judge.setCowl(new CopyOnWriteArrayList<>(list));}
}
5.运行结果(节选)
(start)
==============start judge=================
==============end judge=================tom0本次跑了 2 米,共跑了 2 米
tom3本次跑了 1 米,共跑了 1 米
tom1本次跑了 1 米,共跑了 1 米
tom5本次跑了 1 米,共跑了 1 米
tom9本次跑了 3 米,共跑了 3 米
tom6本次跑了 3 米,共跑了 3 米
tom8本次跑了 2 米,共跑了 2 米
tom2本次跑了 3 米,共跑了 3 米
tom4本次跑了 2 米,共跑了 2 米
tom7本次跑了 2 米,共跑了 2 米==============start judge=================
==============end judge=================
...tom5本次跑了 2 米,共跑了 98 米
tom1本次跑了 3 米,共跑了 97 米
tom8本次跑了 3 米,共跑了 97 米
tom4本次跑了 2 米,共跑了 95 米
tom6本次跑了 2 米,共跑了 91 米
tom9本次跑了 1 米,共跑了 95 米
tom7本次跑了 2 米,共跑了 93 米
tom2本次跑了 2 米,共跑了 92 米
tom3本次跑了 2 米,共跑了 87 米
tom0本次跑了 3 米,共跑了 97 米==============start judge=================
==============end judge=================tom0本次跑了 3 米,共跑了 100 米
tom5本次跑了 1 米,共跑了 99 米
tom1本次跑了 2 米,共跑了 99 米
tom8本次跑了 2 米,共跑了 99 米
tom4本次跑了 2 米,共跑了 97 米
tom6本次跑了 1 米,共跑了 92 米
tom9本次跑了 3 米,共跑了 98 米
tom7本次跑了 2 米,共跑了 95 米
tom2本次跑了 2 米,共跑了 94 米
tom3本次跑了 1 米,共跑了 88 米==============start judge=================
tom0率先抵达终点!
从结果上来看,在一次"循环"中,屏障操作总是在所有参与者线程全部就绪之后启动,屏障操作运行完成之后,参与者线程才开始执行,这一点在judge()方法中的注释打开后可以很清楚的观察到。
于是去阅读源码,果然如此:
 int index = --count;if (index == 0) {  // trippedboolean ranAction = false;try {final Runnable command = barrierCommand;if (command != null)command.run();//此处调用的run();ranAction = true;nextGeneration();return 0;} finally {if (!ranAction)breakBarrier();}}

本文发布于:2024-01-28 05:55:14,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063925205281.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:栏栅   简单   CyclicBarrier
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23