Java编程思想中的例子
import javax.validation.constraints.Size; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; class TaskPortion implements Runnable{ private static int count; private final int id=count++; private final CountDownLatch latch; private static Random random=new Random(47); public TaskPortion(CountDownLatch latch) { this.latch = latch; } public void run() { try { doWork(); } catch (InterruptedException e) { e.printStackTrace(); } latch.countDown(); } public void doWork() throws InterruptedException { TimeUnit.MILLISECONDS.sleep(random.nextInt(1000)); System.out.println(this+"complete"); } @Override public String toString() { return "TaskPortion: "+String.format("%1$-2d",id); } } class WaitingTask implements Runnable{ private final CountDownLatch latch; private static int count; private final int id=count++; public WaitingTask(CountDownLatch latch) { this.latch = latch; } public void run() { try { latch.await(); System.out.println(this); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public String toString() { return "waiting task pass"+String.format("%1$-2d",id); } } public class CountDownLatchDemo { private static final int SIZE=20; public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); CountDownLatch latch=new CountDownLatch(SIZE); for (int i=0;i<SIZE;i++) executorService.execute(new TaskPortion(latch)); // for (int i = 0; i < SIZE; i++) { executorService.execute(new WaitingTask(latch));
executorService.shutdown();
}
}
}
countdownlatch中有个计数器,当计数器减少到0的时候,释放所有等待的线程,coutDown()会让计数器的值减少,调用await()的线程将会进入等待状态,直到调用countdownlatch使得计数器数值减少到0,所有等待的线程都会开始执行。
CyclicBarrier
这个相对于上面的countdownlatch来说,这种可以重复的使用,而且await()已经具备countdownlatch中的countdown()和await()两种方法的作用。(前者await()被线程调用一次计数减一,后者不会,只能通过countdown())
首先了解他的构造方法。
方法
自己独立敲了一段书上的模拟赛马的demo(来自于Java编程思想)
import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.*; class Horse implements Runnable{ private CyclicBarrier barrier; //ByclicBarrier用来控制本类的在释放屏障之前的动作,由构造函数传入 private int stride=0; //马跑得轨迹 private static int count; //马的数量 private final int id=count++; //设置马的id private Random random = new Random(47); //模拟赛马 public Horse(CyclicBarrier barrier) { this.barrier = barrier; } @Override public void run() { try{ while(!Thread.interrupted()){ //这里模拟赛马的过程 TimeUnit.MILLISECONDS.sleep(500); barrier.await(); stride+=random.nextInt(3); } }catch(Exception e){ e.printStackTrace(); } } @Override public String toString() { return "Horse "+id+" "; } public String getTrack(){ StringBuilder s=new StringBuilder();//返回马当前到达屏障之后走的路径 for (int i = 0; i < stride; i++) { s.append("="); } return s.toString(); } public int getStride() { return stride; //马走了多少 } public int getId() { return id; } } class HorseRace { private int nhorse; private ExecutorService exec; private final int FINISH_LINE = 75; private CyclicBarrier barrier; List<Horse> horses = new ArrayList<Horse>(); private String track;
public HorseRace(int nhorse, ExecutorService executorService) { exec = executorService; this.nhorse = nhorse; StringBuilder s = new StringBuilder(); for (int i = 0; i < FINISH_LINE; i++) { s.append("="); } track = s.toString(); System.out.println(s.toString()); barrier = new CyclicBarrier(nhorse, () -> { //表达式中定义了释放屏障之前的动作,打印当前所有马的路程并且判断是否有的码已经到达终点 System.out.println(track); for (Horse horse : horses) { System.out.println(horse.getTrack()); if (horse.getStride() > FINISH_LINE) { System.out.println(horse.getId() + " won"); exec.shutdownNow(); return; } } }); for (int i = 0; i < nhorse; i++) { Horse horse = new Horse(barrier); exec.execute(horse); horses.add(horse); } } } public class HorseRaceDeno { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); new HorseRace(7, executorService); } }