参考:
CountDownLatch
countDown() 方法执行完只是计数器减一, 并不会阻塞当前运行线程的的后续代码执行.
1 package org.wzh.cc; 2 3 import java.util.Arrays; 4 import java.util.Random; 5 import java.util.concurrent.CountDownLatch; 6 import java.util.stream.IntStream; 7 8 import static java.lang.System.out; 9 10 public class D4CountDownLatch {11 12 class Task extends Thread {13 14 private CountDownLatch latch;15 private int time;16 17 public Task(CountDownLatch latch) {18 super();19 this.latch = latch;20 time = score();21 }22 23 private int score() {24 return (new Random().nextInt(8000) + 10000) / 1000;25 }26 27 @Override28 public void run() {29 // TODO Auto-generated method stub30 try {31 String name = currentThread().getName();32 out.println(name + " 预计成绩 " + time + " seconds");33 out.println(name + " 正在冲刺");34 sleep(time * 1000);35 out.println(name + " 到达终点!");36 latch.countDown();//跑完减一37 } catch (InterruptedException e) {38 e.printStackTrace();39 }40 }41 }42 43 public static void main(String[] args) throws InterruptedException {44 out.println("-- 百米赛跑比赛 --");45 out.println("参赛选手:");46 String[] names = {"小明", "小强", "小智"};47 Arrays.stream(names).forEach(out::println);48 out.println("########## 比赛开始 #########");49 50 CountDownLatch latch = new CountDownLatch(names.length);51 IntStream.range(0, names.length).forEach(i -> {52 Thread t = new D4CountDownLatch().new Task(latch);53 t.setName(names[i]);54 t.start();55 });56 latch.await();//当latch countDown指定的次数之后才会继续向下执行57 out.println("百米赛跑比赛结束");58 }59 }
CyclicBarrier
await() 方法阻塞后面的代码,直到达到条件才继续向下执行.
1 package org.wzh.cc; 2 3 import java.util.Arrays; 4 import java.util.Random; 5 import java.util.concurrent.BrokenBarrierException; 6 import java.util.concurrent.CyclicBarrier; 7 import java.util.stream.IntStream; 8 9 import static java.lang.System.out;10 11 public class D4CyclicBarrier {12 13 class Task extends Thread {14 15 private CyclicBarrier barrier;16 private int time;17 18 public Task(CyclicBarrier barrier) {19 super();20 this.barrier = barrier;21 time = score();22 }23 24 private int score() {25 return (new Random().nextInt(8000) + 10000) / 1000;26 }27 28 @Override29 public void run() {30 try {31 String name = currentThread().getName();32 System.out.println(name + " 预计成绩 " + time + " seconds");33 barrier.await();//线程阻塞在这边,直到所有参与的线程都到达这里34 out.println(name + " 正在冲刺");35 sleep(time * 1000);36 out.println(name + " 到达终点!");37 } catch (InterruptedException e) {38 e.printStackTrace();39 } catch (BrokenBarrierException e) {40 e.printStackTrace();41 }42 }43 }44 45 public static void main(String[] args) {46 try {47 out.println("-- 百米赛跑比赛 --");48 out.println("参赛选手:");49 String[] names = {"小明", "小强", "小智"};50 Arrays.stream(names).forEach(out::println);51 out.println("########## 比赛开始 #########");52 53 CyclicBarrier barrier = new CyclicBarrier(names.length + 1);//***54 IntStream.range(0, names.length).forEach(i -> {55 Thread t = new D4CyclicBarrier().new Task(barrier);56 t.setName(names[i]);57 t.start();58 });59 barrier.await();60 System.out.println("百米赛跑比赛结束");61 } catch (Exception e) {62 e.printStackTrace();63 }64 }65 66 }
对比
区别
CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:
CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;
而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;
另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。