CyclicBarrier 试用

简述:

《Java编程思想》 第四版 P724 ~ P726

CyclicBarrier 适用于这样的情况:你希望创建一组人物,他们并行地执行工作,然后在进行下一个步骤之前等待,直至所有任务都完成




Horse.java

package com.anialy.test.concurrency.cyclicbarrier;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public 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 CyclicBarrier barrier;
	
	public Horse(CyclicBarrier b){
		this.barrier = b;
	}
	
	public synchronized int getStrides(){
		return strides;
	}
	
	public void run() {
		try {
			while(!Thread.interrupted()){
				synchronized (this) {
					// random strides per round
					strides += rand.nextInt(3);
				}
				//Waits until all parties have invoked await on this barrier. 
				barrier.await();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}
	
	public String toString(){
		return "Horse " + id + " "; 
	}

	public String tracks(){
		StringBuilder s = new StringBuilder();
		for(int i=0; i<getStrides(); i++){
			s.append("*");
		}
		s.append(id);
		return s.toString();
	}
}


HorseRace.java

package com.anialy.test.concurrency.cyclicbarrier;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class HorseRace {
	private static final int FINISH_LINE = 75;
	
	private List<Horse> horses = new ArrayList<Horse>();
	
	private ExecutorService exec = Executors.newCachedThreadPool();
	
	private CyclicBarrier barrier;
	
	public HorseRace(int nHorses, final int pause){
		barrier = new CyclicBarrier(nHorses, new Runnable(){
			public void run() {
				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;
					}
				}
				try {
					TimeUnit.MILLISECONDS.sleep(pause);
				} catch (InterruptedException e) {
				    System.out.println("barrier-action sleep interrupted");
				}
			}
		});
		
		for(int i=0; i<nHorses; i++){
			Horse horse = new Horse(barrier);
			horses.add(horse);
			exec.execute(horse);
		}
	}
}


Test.java

package com.anialy.test.concurrency.cyclicbarrier;

public class Test {
	public static void main(String[] args) {
		int nHorses = 7;
		int pause = 200;
		new HorseRace(nHorses, pause);
	}
}


输出:




通过使用CyclicBarrier的await在每一回合的数值变化中,直到所有子线程都完成更新才会进入下一轮线程执行。




























猜你喜欢

转载自blog.csdn.net/anialy/article/details/42318821
今日推荐