CyclicBarrier的使用-赛马程序
程序员文章站
2022-06-24 19:45:37
import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;/** * @Author...
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @Author: thunder
* @Date: 2020/7/30 15:17
*/
class Horse implements Runnable {
private static int counter = 0;
private final int id = counter++;
private int strides = 0;//步数
private static Random rand = new Random(47);//随机数
private static CyclicBarrier barrier;
public Horse(CyclicBarrier b) { barrier = b; }
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"到达跑到屏障点,准备开始比赛>>>");
//这里设置屏障点,表白Horse一起开跑
barrier.await();
//线程没有中断就会继续执行
while(!Thread.interrupted()) {
System.out.println(Thread.currentThread().getName()+"正在奔跑"+System.currentTimeMillis());
//这里不需要加锁,因为同一对象并没有被多个线程同时访问的情况,如果出现了被多个线程同时访问的情况,需要添加锁
//synchronized(this) {
//赛马每次随机跑几步,步数会发生变化
strides += rand.nextInt(3);
//}
//新的屏障点,HorseRace打印Horse轨迹,会再次执行HorseRace run()方法
barrier.await();
}
} catch(Exception e) {
e.printStackTrace();
}
}
public String tracks() {
StringBuilder s = new StringBuilder();
for(int i = 0; i < getStrides(); i++) {
s.append("*");
}
//添加horse编号
s.append(id);
return s.toString();
}
//这里不需要加锁,因为同一对象并没有被多个线程同时访问的情况,如果出现了被多个线程同时访问的情况,需要添加锁
int getStrides() { return strides; }
public String toString() { return "Horse " + id + " "; }
}
public class HorseRace implements Runnable {
private static final int FINISH_LINE = 100;
private static List<Horse> horses = new ArrayList<Horse>();
private static ExecutorService exec = Executors.newCachedThreadPool();
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在打印运动轨迹");
StringBuilder s = new StringBuilder();
//打印赛道边界
for(int i = 0; i < FINISH_LINE; i++) {
s.append("=");
}
System.out.println(s);
//打印赛马轨迹
for(Horse horse : horses) {
System.out.println(horse.tracks());
}
//判断是否结束
for(Horse horse : horses) {
if(horse.getStrides() >= FINISH_LINE) {
System.out.println(horse + "won!");
exec.shutdownNow();
return;
}
}
//休眠一会儿再次打印Horse轨迹时间
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch(InterruptedException e) {
System.out.println("barrier-action sleep interrupted");
}
}
public static void main(String[] args) {
//new HorseRace(),定义所有线程到达屏障后执行的操作,由最后到达的线程执行,最后到达的线程执行完毕后(没有和其他线程并发执行),其他线程再并行执行
CyclicBarrier barrier = new CyclicBarrier(7, new HorseRace());
for(int i = 0; i < 7; i++) {
//线程实例
Horse horse = new Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
}
}
参考:
https://blog.csdn.net/weixin_41050155/article/details/79814304
本文地址:https://blog.csdn.net/u011582840/article/details/107693947
上一篇: 减肥中餐吃什么?减肥餐还需要搭配什么?
推荐阅读
-
C#程序提示“正由另一进程使用,因此该进程无法访问该文件”的解决办法
-
网站使用的现有的cms程序是否会影响排名
-
在Python程序中操作文件之flush()方法的使用教程
-
在Python程序中操作文件之isatty()方法的使用教程
-
使用IronPython把Python脚本集成到.NET程序中的教程
-
微信小程序新增的拖动组件movable-view使用教程
-
使用命令行安装驱动程序的方法
-
微信小程序授权 获取用户的openid和session_key【后端使用java语言编写】,我写的是get方式,目的是测试能否获取到微信服务器中的数据,后期我会写上post请求方式。
-
PHP程序级守护进程的实现与优化的使用概述
-
使用C#编写简单的图形化的可发送附件的邮件客户端程序