参考:http://www.importnew.com/21889.html
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 @Override 28 public void run() { 29 // TODO Auto-generated method stub 30 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 @Override 29 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是可以重用的。