Java的并发包中有各种并发类,今天通过这个例子来熟悉使用CyclicBarrier类。

CyclicBarrier类就像一个起跑线,定义了赛道的大小,当所有运动员(多线程)同时在起跑线,

那么CyclicBarrier就会触发起跑动作。

以下是Java使用CyclicBarrier模拟运动比赛的例子

新建一个gradle工程,目录结构如下

在build.gradle中引入spring和lombok两个架包

plugins {id 'java'
}group 'com.drama'
version '1.0-SNAPSHOT'sourceCompatibility = 1.8repositories {maven {url 'http://179.179.179.46:8087/repository/maven-public/'}
}dependencies {compile("org.springframework:spring-context:4.1.6.RELEASE")compile("org.projectlombok:lombok:1.18.8")testCompile group: 'junit', name: 'junit', version: '4.12'
}

定义配置类MyConfig,定义线程池的大小,这里定为6

package demo.cyclicbarrier;import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;@Configuration
@ComponentScan("demo.cyclicbarrier")
@EnableAsync
public class MyConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(6);    //这里的CorePoolSize一定要大于6(1个干扰者,5个运动员)executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.initialize();return executor;}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return null;}
}

定义运动比赛类型和顺序

package demo.cyclicbarrier;import lombok.Getter;public enum SportEnum {Swim("游泳"),Run("跑步"),Cycle("骑车");@Getterprivate final String sportName;SportEnum(String sportName) {this.sportName = sportName;}public SportEnum nextSport(){if(this == Swim)return Run;else if(this == Run)return Cycle;elsereturn Swim;}
}

定义MySignal,用CyclicBarrier表示起跑线,用SportEnum表示比赛状态

package demo.cyclicbarrier;import lombok.Getter;
import lombok.Synchronized;import java.util.concurrent.CyclicBarrier;public class MySignal {@Getterprivate final CyclicBarrier startLine;@Getterprivate SportEnum sport;private String winner;public MySignal(int size) {this.startLine = new CyclicBarrier(size,new StartLine(this));sport = SportEnum.Swim;}@Synchronizedpublic void nextSport(){sport = sport.nextSport();}@Synchronizedpublic boolean setWinner(String winner){if(this.winner==null){this.winner = winner;return true;}return false;}}class StartLine implements Runnable{private final MySignal mySignal;StartLine(MySignal mySignal) {this.mySignal = mySignal;}@Overridepublic void run() {System.out.println(mySignal.getSport().getSportName()+" 比赛开始");mySignal.nextSport();}
}

定义运动员的动作和干扰者的动作,通过@Async来启动多线程

package demo.cyclicbarrier;import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.util.Set;
import java.util.concurrent.BrokenBarrierException;@Service
public class TaskService {@Asyncpublic void troublemaker(){while(true){try {Thread.sleep(100);} catch (InterruptedException e) {}//从程序当前运行线程中,随机取出一个线程出来干扰Set<Thread> threads = Thread.getAllStackTraces().keySet();int size = threads.size();int i = 0;int index = (int)(Math.random()*size);for (Thread thread : threads) {if(i!=index){i++;continue;}thread.interrupt();break;}}}@Asyncpublic void swimming(MySignal mySignal, String name){SportEnum sportEnum = mySignal.getSport();doSport(mySignal, name, sportEnum); //第一场比赛rest(name);sportEnum = mySignal.getSport();doSport(mySignal, name, sportEnum); //第二场比赛rest(name);sportEnum = mySignal.getSport();doSport(mySignal, name, sportEnum); //第三场比赛boolean isWinner = mySignal.setWinner(name);if(isWinner==true){System.out.println("我是 "+name+", 我是冠军");}}private void rest(String name){try {Thread.sleep(1000);} catch (InterruptedException e) {}System.out.println(name+" 休息10分钟");try {Thread.sleep(1000);} catch (InterruptedException e) {}}private void doSport(MySignal mySignal, String name, SportEnum sportEnum){System.out.println(name +" 到达 "+sportEnum.getSportName()+" 起跑线,等待其他人");while(sportEnum==mySignal.getSport()) {try {if(mySignal.getStartLine().isBroken()){try{Thread.sleep(0);}catch (InterruptedException e){}}else{mySignal.getStartLine().await();System.out.println(name + " 开始 " + sportEnum.getSportName());}} catch (InterruptedException e) {System.out.println("我是"+name+",有人干扰我,在起跑线的人都重来");mySignal.getStartLine().reset();} catch (BrokenBarrierException e) {System.out.println("我是"+name+",重新等待 "+sportEnum.getSportName());}}}
}

定义程序入口函数,启动5个运动员和1个干扰者

package demo.cyclicbarrier;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);final int size = 5;TaskService taskService = context.getBean(TaskService.class);MySignal mySignal = new MySignal(size);for(int i=0;i<size;i++){taskService.swimming(mySignal, "man"+i);}taskService.troublemaker();context.close();}
}

程序运行结果,可以看到,只有当所有运动员到达起跑线的时候,比赛才会开始

而且,如果在起跑线的运动员,如果被干扰了,会重置起跑线。

man0 到达 游泳 起跑线,等待其他人
man1 到达 游泳 起跑线,等待其他人
man3 到达 游泳 起跑线,等待其他人
man2 到达 游泳 起跑线,等待其他人
man4 到达 游泳 起跑线,等待其他人
游泳 比赛开始
man4 开始 游泳
man0 开始 游泳
man3 开始 游泳
man1 开始 游泳
man2 开始 游泳
man4 休息10分钟
man3 休息10分钟
man4 到达 跑步 起跑线,等待其他人
man2 休息10分钟
man1 休息10分钟
man0 休息10分钟
我是man4,有人干扰我,在起跑线的人都重来
man3 到达 跑步 起跑线,等待其他人
man1 到达 跑步 起跑线,等待其他人
man2 到达 跑步 起跑线,等待其他人
man0 到达 跑步 起跑线,等待其他人
跑步 比赛开始
man4 开始 跑步
man3 开始 跑步
man1 开始 跑步
man2 开始 跑步
man0 开始 跑步
man2 休息10分钟
man0 休息10分钟
man2 到达 骑车 起跑线,等待其他人
man4 休息10分钟
man3 休息10分钟
man1 休息10分钟
man4 到达 骑车 起跑线,等待其他人
man0 到达 骑车 起跑线,等待其他人
我是man2,有人干扰我,在起跑线的人都重来
我是man4,重新等待 骑车
我是man0,重新等待 骑车
我是man2,有人干扰我,在起跑线的人都重来
我是man4,重新等待 骑车
我是man0,重新等待 骑车
man3 到达 骑车 起跑线,等待其他人
man1 到达 骑车 起跑线,等待其他人
骑车 比赛开始
man2 开始 骑车
我是 man2, 我是冠军
man1 开始 骑车
man4 开始 骑车
man0 开始 骑车
man3 开始 骑车

Java多线程模拟运动比赛相关推荐

  1. Java多线程实现跑步比赛【比赛详解】

    文章目录 文章链接 实现要求 比赛详解 文章链接 Java多线程实现跑步比赛[比赛详解] Java多线程实现跑步比赛[基本设计] Java多线程实现跑步比赛[RunMap--地图映射类] Java多线 ...

  2. java多线程模拟龟兔赛跑,JAVA多线程模拟龟兔赛跑

    JAVA多线程模拟龟兔赛跑! class Rabbit extends Thread{ Tortoise tor; int Journey; int RabbitSpeed; public Rabbi ...

  3. java多线程模拟购买火车票

    java多线程模拟购买火车票 本次做的是一个火车票的售卖模拟,不管用户是在窗口还是APP上购买,必然不可能买到同一张票这也就是说一张票的售卖必然是一个线程在操作的,所以,我们在写代码是也要注意这一点 ...

  4. Java多线程 模拟 购买 退订 机票

     Java多线程 模拟 购买 退订 机票 package cn.com.cloud.sea.thread; /*** @author HenryLee* @version 1.0* 买票*/ publ ...

  5. Java多线程模拟售票系统

    Java创建多线程的两种基本方法: 方法1.继承Thread类 (1)定义子类,继承Thread类,重写该类的run()方法作为线程执行体; (2)创建该子类的实例作为线程对象; (3)调用线程对象的 ...

  6. 利用JAVA多线程模拟售票系统,对统一资源进行处理

    首先多线程处理统一资源的方式有两种 分别介绍一下两者的区别 synchronized与Lock的区别 1.Lock不是Java语言内置的,synchronized是Java语言的关键字 2.synch ...

  7. Java多线程模拟加工厂加工玩具

    创建工厂类, 属性包括:车间类的对象的集合,仓库容量 方法包括: 1. 加工玩具的方法(product),方法的功能是各个车间同时工作.根据仓库容量平均分配给各个车间需要加工玩具的数量.2. 建造玩具 ...

  8. Java 多线程 模拟银行ATM实时存取钱

    近期想回顾一些知识: 一.Java 多线程 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.多线程是多任务的一种特别的形式,但多线程使用了更小的资源开 ...

  9. Java多线程 模拟售票窗口售票

    编写一个Java 多线程程序,完成三个售票窗口同时出售20张票 程序分析: 1.票数要使用同一个静态值: 2.为保证不会出现卖出同一个票数,要java多线程同步锁. 设计思路: 创建一个站台类Stat ...

最新文章

  1. 【IDAX投研中心】BCH果然最强
  2. Linux内核源码结构
  3. python处理多个excel文件-python多个excel文件合并成一个sheet
  4. python求平方根的代码_python如何求平方根
  5. 在线教育开源 java_开源项目SpringBoot在线教育平台
  6. 记一次 IIS 7.0 身份验证相关的问题解决
  7. ST-Link刷成J-Link
  8. 海龟绘图小动物_被解救海龟经野化训练后放归大海,这一幕让人惊叹不已
  9. ssis 循环导入数据_使用集成服务(SSIS)包从Amazon S3 SSIS存储桶导入数据
  10. php7 jpgraph,JpGraph4.0.2中文乱码以及在php7.0版本无法显示的解决办法
  11. lua和torch的安装
  12. IO负载高的来源定位 IO系列
  13. 解方程c语言程序,C语言程序解线性方程组
  14. 【细胞分割】基于matlab GUI原子力显微镜图像分析【含Matlab源码 1371期】
  15. java opencv 基本操作4
  16. 看完《第一行代码-第三版》- 郭霖 这本书后的总结
  17. DNS、HTTP劫持的一些事
  18. python写数学公式大全_数学公式书写
  19. 疫情推动“宅经济”成为当前重要经济发展模式
  20. C语言有趣的代码大全,分享一段有趣的小代码

热门文章

  1. [18调剂]北方民族大学2018年硕士研究生调剂公告
  2. 这家小米生态链公司用AI+学习,重塑儿童手表市场
  3. 【R文档】1 isolation.forest/孤立森林算法
  4. 2020年腾讯丶百度丶字节丶OPPO等Android面试大全,附带教你如何写好简历
  5. 终于还是对B站动漫动手了!【数据可视化分析】
  6. maven错误Unknown lifecycle phase “build“. You must specify a valid lifecycle phase or a goal in the fo
  7. python上市公司_Python批量下载上交所上市公司报告
  8. 计算机c盘空间满了应该怎么办,电脑c盘空间满了怎么办?教你12个方法解决电脑c盘空间不足的问题...
  9. “牌面”养成记4:阅读顺序,工具,以及小成果
  10. 2019经济寒冬,软件定制开发公司的竞争力在哪里??