java CountDownLatch(闭锁)
2016-04-12 20:35
447 查看
CountDownLatch的和join有类似之处,但是比join强大并且灵活许多。
在实例化一个CountDownLatch时,需要设置一个初始计数,所有调用await()方法的线程都会阻塞直到计数减为零,countDown()方法每调用一次 ,计数减一直到减为零从而唤醒其他所有调用await()方法的线程。
CountDownLatch的计数功能是一次性的,即它的计数减为零时,不能再重新设置它的值。
当CountDownLatch初始化计数设置为1时,它可以作为一个开关或者门(a simple on/off latch, or gate),即所有调用await()方法的线程都必须等待一个线程调用CountDown()方法,那么就相当于一个开关,只有调用countDown()之后线程才可以通过。
当CountDownLatch初始计数置为N时,调用await()方法的线程必须等待N个线程调用完成某个事件。
和join最大的区别是等待线程是等待其他N个线程调用CountDown()方法而不是线程结束。
来看一个例子(一个货车司机和几个码头工人,首先码头工人需要等待火车司机把车开到码头才能装货,其次货车司机需要等待所有的工人将货物装上车它才能把车开走)
在实例化一个CountDownLatch时,需要设置一个初始计数,所有调用await()方法的线程都会阻塞直到计数减为零,countDown()方法每调用一次 ,计数减一直到减为零从而唤醒其他所有调用await()方法的线程。
CountDownLatch的计数功能是一次性的,即它的计数减为零时,不能再重新设置它的值。
当CountDownLatch初始化计数设置为1时,它可以作为一个开关或者门(a simple on/off latch, or gate),即所有调用await()方法的线程都必须等待一个线程调用CountDown()方法,那么就相当于一个开关,只有调用countDown()之后线程才可以通过。
当CountDownLatch初始计数置为N时,调用await()方法的线程必须等待N个线程调用完成某个事件。
和join最大的区别是等待线程是等待其他N个线程调用CountDown()方法而不是线程结束。
来看一个例子(一个货车司机和几个码头工人,首先码头工人需要等待火车司机把车开到码头才能装货,其次货车司机需要等待所有的工人将货物装上车它才能把车开走)
public class Diver { public static void main(String[] args) throws InterruptedException{ CountDownLatch canDrive = new CountDownLatch(5);//有五个工人 CountDownLatch canLoad = new CountDownLatch(1); //五个工人在等待 for(int i = 0; i < 5; i++){ new Thread(new Worker(canDrive,canLoad),"" + i).start(); } Thread.sleep(400);//让工人线程先执行 System.out.println("老司机把车开来了"); canLoad.countDown(); canDrive.await(); System.out.println("老司机把车开走了"); } } class Worker implements Runnable{ private CountDownLatch canDrive;//开车开关 private CountDownLatch canLoad;//装货开关 public Worker (CountDownLatch canDrive, CountDownLatch canLoad){ this.canDrive = canDrive; this.canLoad = canLoad; } @Override public void run() { try { System.out.println(Thread.currentThread().getName() + ": 在等车来啊"); canLoad.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ": 我把货装好了"); canDrive.countDown(); try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "装完货我得抽根烟冷静一下"); } } result: 0: 在等车来啊 1: 在等车来啊 2: 在等车来啊 3: 在等车来啊 4: 在等车来啊 老司机把车开来了 0: 我把货装好了 1: 我把货装好了 3: 我把货装好了 4: 我把货装好了 2: 我把货装好了 老司机把车开走了 0装完货我得抽根烟冷静一下 1装完货我得抽根烟冷静一下 3装完货我得抽根烟冷静一下 2装完货我得抽根烟冷静一下 4装完货我得抽根烟冷静一下
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树