您的位置:首页 > 其它

2.8.等待多个并发完成

2014-05-05 22:04 351 查看

等待多个并发完成

经常会有这种场景:在主线程中启动多个工作线程,然后主线程需要等待工作线程全部完成后再进行下一步处理。如何实现等待多个线程完成?用Thread.join方法?这种方式耦合性太强,而且太土了!Java5引入了新的机制,这个机制语义明确、功能强大、使用灵活,这就是CountDownLatch类。

CountDownLatch类是同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一致等待。这个类的构造函数需要传入一个整数,这个整数就是要等待完成操作的数目。一个线程要等待某些操作现执行完时,需要调用await()方法,这个方法让线程进入休眠直到等待的所有操作完成。当某一个操作完成后,它将调用countDown()方法将CountDownLatch的内部计数器减1。当计数器变成0的时候,CountDownLatch将唤醒所有调用await()方法而进入休眠的线程。

CountDownLatch和其他同步方法不同,它不是用来保护共享资源或者临界区的,而是用来同步执行多个任务的线程。CountDownLatch只准许进入一次,一旦内部计数器为0后,再调用方法将不起作用。

下面一个参加会议的例子说明CountDownLatch的作用和用法。主线程发起多个参会者,每个参会者都是一个线程,主线程需要等到所有参会者都到达之后才能开始会议。示例代码如下:

public class CountDownLatchDemo {

public static void main(String[] args){
CountDownLatch latch = new CountDownLatch(10);
Thread mettingThread = new Thread(new Metting(latch));
Thread[] assigneerThreads = new Thread[10];
Assigneer assigneer = new Assigneer(latch) ;

for(int i=0; i<latch.getCount(); i++){
Thread t = new Thread(assigneer);
assigneerThreads[i] = t;
}

System.out.println("main:启动会议线程");
mettingThread.start();
System.out.println("main:启动参会线程");
for(int i=0; i<assigneerThreads.length; i++){
assigneerThreads[i].start();
}

//等待参会线程结束
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main:退出");
}
}

/** 参会线程**/
class Assigneer implements Runnable{
private CountDownLatch latch ;

Assigneer(CountDownLatch latch) {
this.latch = latch;
}

@Override
public void run() {
System.out.println("参会线程:参会者:" + Thread.currentThread().getName() + "。参加会议....");
long delay = (long)(Math.random()*1000);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.latch.countDown();
}
}

/** 会议线程**/
class Metting implements Runnable{
private CountDownLatch latch ;

Metting(CountDownLatch latch){
this.latch = latch;
}
@Override
public void run() {
System.out.println("会议线程:参会者数:" + this.latch.getCount() + "。等待参会者....");
try {
latch.await();
System.out.println("会议线程:参会者全部到达,开始会议...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


程序运行日志:

main:启动会议线程
main:启动参会线程
会议线程:参会者数:10。等待参会者....
参会线程:参会者:Thread-1。参加会议....
参会线程:参会者:Thread-3。参加会议....
参会线程:参会者:Thread-2。参加会议....
参会线程:参会者:Thread-4。参加会议....
参会线程:参会者:Thread-5。参加会议....
参会线程:参会者:Thread-6。参加会议....
参会线程:参会者:Thread-8。参加会议....
参会线程:参会者:Thread-7。参加会议....
参会线程:参会者:Thread-9。参加会议....
参会线程:参会者:Thread-10。参加会议....
会议线程:参会者全部到达,开始会议...
main:退出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐