您的位置:首页 > 其它

CyclicBarri和 CountDownLatch的使用场景

2017-10-14 11:42 274 查看

CyclicBarrier的用法

CyclicBarrier和CountDownLatch一样,都是关于线程的计数器。

用法略有不同,测试代码如下:

1 public class TestCyclicBarrier {
2
3     private static final int THREAD_NUM = 5;
4
5     public static class WorkerThread implements Runnable{
6
7         CyclicBarrier barrier;
8
9         public WorkerThread(CyclicBarrier b){
10             this.barrier = b;
11         }
12
13         @Override
14         public void run() {
15             // TODO Auto-generated method stub
16             try{
17                 System.out.println("Worker's waiting");
18                 //线程在这里等待,直到所有线程都到达barrier。
19                 barrier.await();
20                 System.out.println("ID:"+Thread.currentThread().getId()+" Working");
21             }catch(Exception e){
22                 e.printStackTrace();
23             }
24         }
25
26     }
27
28     /**
29      * @param args
30      */
31     public static void main(String[] args) {
32         // TODO Auto-generated method stub
33         CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {
34             //当所有线程到达barrier时执行
35             @Override
36             public void run() {
37                 // TODO Auto-generated method stub
38                 System.out.println("Inside Barrier");
39
40             }
41         });
42
43         for(int i=0;i<THREAD_NUM;i++){
44             new Thread(new WorkerThread(cb)).start();
45         }
46     }
47
48 }
49 /*
50 以下是输出:
51 Worker's waiting
52 Worker's waiting
53 Worker's waiting
54 Worker's waiting
55 Worker's waiting
56 Inside Barrier
57 ID:12 Working
58 ID:8 Working
59 ID:11 Working
60 ID:9 Working
61 ID:10 Working
62 */


 CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。 
 CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 
 CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。

CountDownLatch的用法


让我们尝试罗列出在java实时系统中CountDownLatch都有哪些使用场景。我所罗列的都是我所能想到的。如果你有别的可能的使用方法,请在留言里列出来,这样会帮助到大家。

实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。
开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。
死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。

CountDownLatch使用例子

在这个例子中,我模拟了一个应用程序启动类,它开始时启动了n个线程类,这些线程将检查外部系统并通知闭锁,并且启动类一直在闭锁上等待着。一旦验证和检查了所有外部服务,那么启动类恢复执行。

BaseHealthChecker.java:这个类是一个Runnable,负责所有特定的外部服务健康的检测。它删除了重复的代码和闭锁的中心控制代码。

NetworkHealthChecker.java:这个类继承了BaseHealthChecker,实现了verifyService()方法。DatabaseHealthChecker.java[b]CacheHealthChecker.java[/b]除了服务名和休眠时间外,与NetworkHealthChecker.java是一样的。

ApplicationStartupUtil.java:这个类是一个主启动类,它负责初始化闭锁,然后等待,直到所有服务都被检测完。

现在你可以写测试代码去检测一下闭锁的功能了。

常见面试题

可以为你的下次面试准备以下一些CountDownLatch相关的问题:

解释一下CountDownLatch概念?
CountDownLatch 和CyclicBarrier的不同之处?
给出一些CountDownLatch使用的例子?
 CountDownLatch 类中主要的方法?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: