java多线程等待协调工作:CountDownLatch类的高级应用
2016-07-06 10:58
351 查看
一:说明
基本上对于线程初步了解的人,都是使用synchronized来同步线程的,也确实,它也是可以满足一些常用的问题。那么我们来说一些它不能解决的问题(其实是不怎么好解决的问题,并不是真的不能解决)1.1:场景一
问题:在一场运动会上,有10个运动员,只有当10个运动员都准备完毕后,所有人才能一起跑,否则就算前面的运动员在几天前都做好准备了,只要最后一个运动员没有做好准备,那所有的人都不能跑,有失公平嘛!
常规的解决方法
定义一个计数器,并且对它的操作进行同步,当每有一个准备完毕后,增加这个计数器的准备好的数量,当达到10个的时候,全部一起运行,那么大概的代码是这样子的,程序要定义一个死循环,只有当所有的条件满足的时候,才能往下走,否则就一直循环。
1.2:场景二:多线程下载文件,我们使用它来作为例子
为了提高下载效率,充分利用网络资源,决定使用多线程来下载一个文件,那么每一个线程分别下载一小段文件,当所有的文件下载完之后,对所有的文件进行合并,那就得到完整的文件了。
理论上来说代码是这样子的(理论上,实际上是错误的)
public static void go(){ System.out.println("开始下载文件,开启10个线程下载"); for(int i = 0 ; i < 10 ; i ++){ new Thread(){ public void run(){ System.out.println("文件下载完成"); } }.start(); } //开始合并文件 System.out.println("所有文件下载完成,开始合并文件"); }
上面的代码开启了10个线程去下载文件,下载完之后,执行合并文件的方法,但是由于多线程,合并文件的时候,线程肯定是没有执行完成的。
要怎么办呢?这个时候命名用synchronized肯定是没用的,synchronized只是使得同一时间只有一个线程通过
二:CountDownLatch使用所有的线程等待。
CountDownLatch这个类,可以使得所有的线程,全部停在那一个位置,达到指定的条件的时候,才可以运行。先给出代码public static void main(String[] args) throws Exception { //这里的构造方法参数是指需要达到完成的数量个数 final CountDownLatch cd = new CountDownLatch(10); for(int i = 0 ; i < 10 ; i ++){ new Thread(){ public void run(){ System.out.println("文件下载完成"); //还记得之前构造方法的参数吗,10,每调用一个countDown()方法,都会使得这个数值减1 cd.countDown(); } }.start(); } //这个方法,会使得所有的线程暂停,只有当cd构造方法里面的值为0的时候,才能走通,调用一个countDown()方法,都会使得这个数值减1 cd.await(); //或者使用这个方法,这个方法也会等待数值到0才会往下面走,但是如果达到指定的时间,还没有达到0,它也会走过 // cd.await(1000, TimeUnit.MINUTES); //开始合并文件 System.out.println("所有文件下载完成,开始合并文件"); }
执行结果是这样的
文件下载完成 文件下载完成 文件下载完成 文件下载完成 文件下载完成 文件下载完成 文件下载完成 文件下载完成 文件下载完成 文件下载完成 所有文件下载完成,开始合并文件
这样就满足条件啦
相关文章推荐
- 【Java讨论】引用类型赋值为null对加速垃圾回收的作用(转载)
- ZooKeeper Java例子(六)
- java多线程机制
- struts2基础——请求与响应、获取web资源
- 华为机试---完全数计算
- java中的异常
- 使用Spring整合Hibernate出现无法自动建立表的问题
- 三维装箱问题Java代码的简单实现过程
- 在WebService中使用Retrofit+RxJava
- org.springframework.beans.factory.BeanNotOfRequiredTypeException must be of type
- java协变类型返回
- SpringMVC参数传递方式
- 《Spring源码分析》——JDBC章节
- java 二叉树(三)递归遍历二叉树
- spring源码分析之<context:component-scan/>vs<annotation-config/>
- 一种c#深拷贝方式完胜java深拷贝(实现上的对比)
- springmvc mybatis集成
- Java持久层框架MyBatis简单实例
- Java 内部类种类及使用解析
- JavaEE第一天_html标签