CountDownLatch与CyclicBarrier使用以及区别
区别:
CountDownLatch : 一个线程(或者多个),等待另外N个线程完成某个事情之后才能执行。
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
- CountDownLatch
package com.king.test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*
* @author paul
*
* CountDownLatch 很适合用来将一个任务分为n个独立的部分,等这些部分都完成后继续接下来的任务,
* CountDownLatch 只能出发一次,计数值不能被重置。
*
* 基于CountDownLatch 的模拟项目,一个项目可以分为多个模块,只有但这些模块都完成后才可以继续下一步的工作。
*
*
* countDown方法,当前线程调用此方法,则计数减一
await方法,调用此方法会一直阻塞当前线程,直到计时器的值为0
executorService.shutdown() 并不是终止线程的运行,而是禁止在这个Executor中添加新的任务
void shutdown()
启动一个关闭命令,不再接受新任务,当所有已提交任务执行完后,就关闭。如果已经关闭,则调用没有其他作用。
抛出:
SecurityException - 如果安全管理器存在并且关闭,此 ExecutorService 可能操作某些不允许调用者修改的线程
(因为它没有保持 RuntimePermission("modifyThread")),或者安全管理器的 checkAccess 方法拒绝访问。
*/
public class CountDownLatchTest {
public static void main(String[] args) {
int size = 10;
CountDownLatch latch = new CountDownLatch(size);
ExecutorService executorService = Executors.newCachedThreadPool();
MyThread t = new MyThread(latch);
executorService.execute(t);
for (int i=0;i<size;i++){
executorService.execute(new Model("模块"+i,latch));
}
executorService.shutdown();
}
}
class MyThread implements Runnable{
CountDownLatch latch;
MyThread(CountDownLatch latch){
this.latch = latch;
}
public void run(){
System.out.println("开始准备资源.....");
try {
latch.await();
} catch (Exception e){
e.printStackTrace();
}
System.out.println("所以资源准备妥当.....");
}
}
class Model implements Runnable{
CountDownLatch latch = null;
String name;
Model(String name,CountDownLatch latch){
this.name = name;
this.latch = latch;
}
public void run(){
System.out.println(name+"执行了");
try {
latch.countDown();
} catch (Exception e){
e.printStackTrace();
}
}
}
- CyclicBarrier
package com.king.test;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。
* 在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。
* 因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
* CyclicBarrier可以多次重复使用
*
*/
public class CyclicBarrierTest {
public static void main(String[] args) {
int size = 8;
final CyclicBarrier cyclicBarrier = new CyclicBarrier(size, new Runnable() {
@Override
public void run() {
System.out.println("所有执行完毕");
}
});
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i=0;i<size;i++){
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"准备好了");
try {
cyclicBarrier.await();
} catch (Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"开始执行");
}
});
}
}
}