用线程模拟,CountDownLatch,CyclicBarrier
来源:互联网 发布:js 范围选择滑块插件 编辑:程序博客网 时间:2024/05/16 06:13
之前从网上看到一段代码,关于wait和notify的,但是发现代码写的有bug,并且程序的逻辑我感觉并不是太清楚,但是程序所举的例子还是很有意义的。
因此我改写了一下,用面向对象的思维。
import java.util.Collection;import java.util.Collections;import java.util.HashSet;import java.util.Set;import java.util.concurrent.atomic.AtomicInteger;/** * 用于模拟在一个game中先让运动员全体准备好,然后一起开始game * * @author donggua * */public class Game {public static AtomicInteger readPlayerCount = new AtomicInteger(0);// 运动员的数量private Set<Athlete> players = new HashSet<Athlete>();// 用于存放运动员,表示参与这个game的集合public void addPlayer(Athlete one) {players.add(one);}public void removePlayer(Athlete one) {players.remove(one);}public Collection<Athlete> getPlayers() {return Collections.unmodifiableSet(players);}/** * game的准备阶段,表示通知所有的运动员准备好 */public void prepare() {for (Athlete player : players) {player.ready();}}/** * game开始,通知所有的运动员开始 */public void go() {synchronized (Game.class) {Game.class.notifyAll();}}public static void main(String[] args) {Game game = new Game();for (int i = 0; i < 10; i++) {game.addPlayer(new Athlete(i));}game.prepare();while (true) {if (readPlayerCount.get() == 10) {// 所有的运动员准备好之后,game开始game.go();break;}}}}
/** * 运动员实体类 * * @author donggua * */class Athlete implements Runnable {private final int id;public Athlete(int id) {this.id = id;}public String toString() {return "Athlete<" + id + ">";}public void ready() {new Thread(this).start();}public void run() {synchronized (Game.class) {try {Game.readPlayerCount.addAndGet(1);System.out.println(this + " ready!");Game.class.wait();System.out.println(this + "go");} catch (InterruptedException e) {e.printStackTrace();}}}}
上面是用到了synchronized,notifyAll ,wait等java原生的方式实现了这一功能,但是jdk中还是提供了更加面向对象的实现如:CountDownLatch 和CyclicBarrier
下面就用这两个类分别改写上面的程序:
import java.util.concurrent.CountDownLatch;/** * 运动员实体类 * * @author donggua * */class AthleteCountDownLatch implements Runnable {private int id;private CountDownLatch startSignal;private CountDownLatch doneSignal;AthleteCountDownLatch(CountDownLatch startSignal, CountDownLatch doneSignal, int id) {this.startSignal = startSignal;this.doneSignal = doneSignal;this.id = id;}public AthleteCountDownLatch(int id) {this.id = id;}public String toString() {return "Athlete<" + id + ">";}public void ready() {new Thread(this).start();}public void run() {try {GameCountLatch.readPlayerCount.addAndGet(1);System.out.println(this.toString() + "ready。。。");startSignal.await();doWork();doneSignal.countDown();} catch (InterruptedException ex) {}}private void doWork() {System.out.println(toString() + "game 进行中。。。。。");}}
import java.util.Collection;import java.util.Collections;import java.util.HashSet;import java.util.Set;import java.util.concurrent.CountDownLatch;import java.util.concurrent.atomic.AtomicInteger;/** * 用于模拟在一个game中先让运动员全体准备好,然后一起开始game * * @author donggua * */public class GameCountLatch {public static AtomicInteger readPlayerCount = new AtomicInteger(0);// 运动员的数量private Set<AthleteCountDownLatch> players = new HashSet<AthleteCountDownLatch>();// 用于存放运动员,表示参与这个game的集合public void addPlayer(AthleteCountDownLatch one) {players.add(one);}/** * game的准备阶段,表示通知所有的运动员准备好 */public void prepare(CountDownLatch startSignal, CountDownLatch doneSignal, GameCountLatch game) {for (int i = 0; i < 10; i++) {game.addPlayer(new AthleteCountDownLatch(startSignal, doneSignal, i));}for (AthleteCountDownLatch player : players) {player.ready();}}/** * game开始,通知所有的运动员开始 */public void go(CountDownLatch startSignal) {while (true) {if (readPlayerCount.get() == 10) {// 所有的运动员准备好之后,game开始startSignal.countDown();break;}}}public static void main(String[] args) {CountDownLatch startSignal = new CountDownLatch(1);CountDownLatch endSignal = new CountDownLatch(10);GameCountLatch game = new GameCountLatch();game.prepare(startSignal, endSignal, game);game.go(startSignal);try {endSignal.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("game 结束");}}
可以看到上面的程序比上上个稍微好一点,关键的是能够得到game结束的时机点。
import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * 运动员实体类 * * @author donggua * */class AthleteCyclicBarrier implements Runnable {private final int id;private CyclicBarrier barrier;public AthleteCyclicBarrier(CyclicBarrier barrier, int id) {this.barrier = barrier;this.id = id;}public String toString() {return "Athlete<" + id + ">";}public void readyAndGo() {new Thread(this).start();}public void run() {synchronized (barrier) {System.out.println(toString() + " ready! 已经有" + (barrier.getNumberWaiting() + 1) + "个准备好了");}try {barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println(toString() + " gameing ...!");try {barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}
import java.util.HashSet;import java.util.Set;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.atomic.AtomicInteger;/** * 用于模拟在一个game中先让运动员全体准备好,然后一起开始game * @author donggua * */public class GameCyclicBarrier {public static AtomicInteger readPlayerCount = new AtomicInteger(0);//运动员的数量private Set<AthleteCyclicBarrier> players = new HashSet<AthleteCyclicBarrier>();//用于存放运动员,表示参与这个game的集合public void addPlayer(AthleteCyclicBarrier one) {players.add(one);}/*** game的准备阶段,表示通知所有的运动员准备好*/public void readyAndGo(CyclicBarrier barrier,GameCyclicBarrier game) {for (int i = 0; i < 10; i++) {game.addPlayer(new AthleteCyclicBarrier(barrier,i));}for(AthleteCyclicBarrier player : players) {player.readyAndGo();}}public static void main(String[] args) {CyclicBarrier cyclicBarrier = new CyclicBarrier(10);GameCyclicBarrier game = new GameCyclicBarrier();game.readyAndGo(cyclicBarrier, game);}}
0 0
- 用线程模拟,CountDownLatch,CyclicBarrier
- 用CountDownLatch和CyclicBarrier处理并发线程
- Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java线程学习笔记CountDownLatch 和CyclicBarrier
- 线程通信——CountDownLatch和CyclicBarrier
- 线程执行顺序——CountDownLatch、CyclicBarrier 、join()、线程池
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier)
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier) .
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier) .
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier)
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier) .
- Java线程计数器CyclicBarrier和CountDownLatch的使用
- 线程状态控制 CountDownLatch和CyclicBarrier的区别
- Java线程学习笔记(十)CountDownLatch 和CyclicBarrier
- Java多线程等待所有线程结束(CountDownLatch/CyclicBarrier)
- Java线程(CountDownLatch、CyclicBarrier、Semaphore)并发控制工具类
- 【Java并发】(二) 线程同步之Thread.join()、CountDownLatch、CyclicBarrier
- CyclicBarrier And CountDownLatch Tutorial
- 最大流算法之-增广路径(path augmentation)and压入与重标记算法(push-relable)
- C语言结构体的使用及注意事项
- 鸟哥的私房菜:Linux文件与目录管理
- [数位dp] ural 1057 Amount of Degrees
- Nyoj 530 K steps[矩阵乘法求两点k步的方案数]
- 用线程模拟,CountDownLatch,CyclicBarrier
- STL标准容器类简介
- 嵌入式 uboot以及kernel添加看门狗临时记录(个人记录未整理乱)
- C#多线程编程总结
- 基于Spring、Hibernate的通用DAO层与Service层的实现
- 解决python3使用cx_Freeze打包成exe后不能运行
- 黑马程序员_java的反射机制
- linux netlink
- [Unity 笔记] 关于 Unity Forward Rendering