Thread--CountDownLatch & CyclicBarrier

参考: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是可以重用的。

posted @ 2018-06-22 16:45  MicroCat  阅读(184)  评论(0编辑  收藏  举报