CountDownLatch解析和应用示例
2017-07-17 17:58
190 查看
前言
在日常处理线程同步问题的时候我们经常联想到的可能有下面几种办法:1.synchronized关键字
2.Java5引入的java.util.concurrent.locks包的显示锁
3.CountDownLatch
今天要说的CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
简单的来说,CountDownLatch就是可以通过这种计数的方式控制线程的执行临界区,举个例子:
我有事务A、B、C、D需要完成,A、B、C是D的前置条件,D事务必须要等A、B、C全部完成后才能开始。
我们就可以通过CountDownLatch去管理这种执行上的先后问题。
实现
打开java.util.concurrent包的CountDownLatch类,可以看到有以下成员方法。几个关键的方法:
- CountDownLatch(int)
初始化一个CountDownLatch,设置闩值,如果闩值未减到0,不执行后续语句
- await()
判断CountDownLatch的值是否已经减到了0,没有的话将一直处于等待状态
- countDown()
供线程完成自己的业务后调用,CountDownLatch初始化的值减1
- getCount()
获取当前CountDownLatch的值
看了CountDownLatch具体的实现方法,关于前言中的例子如何实现,是不是就已经胸有成竹了,我们只需要做下面几件事。
1.为A、B、C三个事务各声明一个线程去执行相关业务代码。
2.声明一个初始值为3的CountDownLatch,用来计数。
3.A、B、C三个事务的线程在执行完成后调用countDown()方法。
4.通过CountDownLatch的await()方法判断A、B、C是否均已完成。
示例
针对上面的例子,模拟了一个应用场景。假设某个新上线项目的部署需要先启动网络服务、DNS服务以及数据服务,在其他三个服务启动前,部署事务一直处于闭锁状态。
Service.java
服务类,声明3个服务对象。
package countDownLatch.service; /** * * @author lenovo * 模拟服务启动 */ public class Service { //服务名 private String serviceName; //服务启动所需时间 private Long startUpMills; public Service(String serviceName, Long startUpMills){ this.serviceName = serviceName; this.startUpMills = startUpMills; } public void startUpService(){ try{ System.out.println("服务"+serviceName+"启动中..."); Thread.sleep(startUpMills); }catch(InterruptedException ie){ ie.printStackTrace(); } System.out.println("服务"+serviceName+"启动完毕..."); } }
ServiceStartupTestThread.java
服务线程类,将每个服务的启动工作交付给线程执行,并完成服务启动前后的相关操作。
package countDownLatch.service; import java.util.concurrent.CountDownLatch; public class ServiceStartupTestThread implements Runnable{ //当前线程内的服务对象 private Service service; //countDownLatch计数器 private CountDownLatch cdl; ServiceStartupTestThread(Service service, CountDownLatch cdl){ this.service = service; this.cdl = cdl; } @Override public void run() { //处理线程绑定的业务逻辑 service.startUpService(); //处理完毕CountDownLatch-1 cdl.countDown(); } }
StartupProject.java
启动项目主方法,在这里判断三个服务是否均已启动完毕。
package countDownLatch.service; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class StartupProject { public static void main(String[] args) { CountDownLatch cdl = new CountDownLatch(3); //创建服务对象 Service netWork = new Service("网络服务", (long)(Math.random()*5000+1000)); Service dns = new Service("DNS服务", (long)(Math.random()*5000+1000)); Service dataSource = new Service("数据服务", (long)(Math.random()*5000+1000)); //为每一个服务提供执行线程 ServiceStartupTestThread netWorkThread = new ServiceStartupTestThread(netWork, cdl); ServiceStartupTestThread dnsThread = new ServiceStartupTestThread(dns, cdl); ServiceStartupTestThread dataSourceThread = new ServiceStartupTestThread(dataSource, cdl); //创建线程list List<ServiceStartupTestThread> serviceList = new ArrayList<ServiceStartupTestThread>(); serviceList.add(netWorkThread); serviceList.add(dnsThread); serviceList.add(dataSourceThread); //创建一个容量适配的连接池 ExecutorService executor = Executors.newFixedThreadPool(serviceList.size()); for(ServiceStartupTestThread t : serviceList){ 4000 executor.execute(t); } //关闭连接池 executor.shutdown(); try { cdl.await(); System.out.println("所有服务已经启动完毕!"); //method()启动项目部署... } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果:
参考文章
感谢!http://www.importnew.com/15731.html
什么时候使用CountDownLatch
http://blog.csdn.net/jackfrued/article/details/44499227
关于Java并发编程的总结和思考
相关文章推荐
- Python解析XML正确应用代码示例讲解
- 【Android 应用开发】Android 图表绘制 achartengine 示例解析
- Jetty架构解析及应用示例
- cJSON的简单应用——保存/解析 Shader 参数 【代码示例】
- 【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )
- C#创建文件的实战应用示例解析
- 【Android 应用开发】Android 图表绘制 achartengine 示例解析
- 【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )
- [技术思考]APUE UNP1/2 的包裹函数的解析与应用示例
- [转]C#创建文件的实战应用示例解析
- Jetty架构解析及应用示例
- python命令行参数解析示例应用
- Android ApiDemos示例解析(97):Views->Animation->Push
- Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例
- 关于骨骼动画及微软示例Skinned Mesh的解析
- Android ApiDemos示例解析(16):App->Activity->Translucent
- PointKeyFrame应用示例
- jBPM 5/jBPM 6 基本概念,示例介绍,深入理解,工作流应用开发指南
- 2017区块链必修课之:区块链技术的商业应用实例解析
- 使用Jsoup简单解析HTML文件示例