java多线程开发之CyclicBarrier,CountDownLatch
2015-05-04 17:23
525 查看
最近研究了一个别人的源码,其中用到多个线程并行操作一个文件,并且在所有线程全部结束后才进行主线程后面的处理。
其用到java.util.concurrent.CyclicBarrier 这个类。
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用,其相当于一个屏障,当一个线程跑到await()方法时,将挂起这个线程,等待直到其他线程同样跑这个await()方法。
其是使用一个计数器,当计数器没有减少到0的时候,则会将当前线程中断。
另外,这个是可以重复等待的,重复调用await()方法,将进行重新等待。
构造方法:
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行
当构造方法传入一个Runnable时,每次到达公共屏障点的时候都最先执行这个传进去的Runnable,然后再执行处于等待的Runnable
另外,其还有一些其他方法
。。
既然提到了CyclicBarrier,就不得不提到另一个相似功能的工具类:CountDownLatch
CyclicBarrier是一个栅栏,其是将走到await()方法的线程进行拦截,直到等待全部的线程走到这个栅栏。
CountDownLatch是一个计数器,其是线程走到await()方法时,进行等待计数,将在计数到达指定值时才继续往下走。
CountDownLatch当计数到0时,计数无法被重置;CyclicBarrier计数达到指定值时,计数置为0重新开始。
CountDownLatch每次调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响;
CyclicBarrier只有一个await()方法,调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞。
主要方法
public CountDownLatch(int count);
publicvoid countDown();
publicvoid await() throws InterruptedException
其用到java.util.concurrent.CyclicBarrier 这个类。
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用,其相当于一个屏障,当一个线程跑到await()方法时,将挂起这个线程,等待直到其他线程同样跑这个await()方法。
int index = --count; if (index == 0) { // tripped //。。 } else { // We're about to finish waiting even if we had not // beeninterrupted, so thisinterrupt is deemed to // "belong" to subsequent execution. Thread.currentThread().interrupt(); }
其是使用一个计数器,当计数器没有减少到0的时候,则会将当前线程中断。
另外,这个是可以重复等待的,重复调用await()方法,将进行重新等待。
构造方法:
CyclicBarrier(int parties)
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行
当构造方法传入一个Runnable时,每次到达公共屏障点的时候都最先执行这个传进去的Runnable,然后再执行处于等待的Runnable
/** * CyclicBarrier类似于CountDownLatch也是个计数器, * 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, * 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 * CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 * CyclicBarrier初始时还可带一个Runnable的参数, * 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。 */ public class CyclicBarrierTest { public staticvoid main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); //final CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点 final CyclicBarrier cb = new CyclicBarrier(3,new Runnable(){ @Override publicvoid run() { System.out.println("********我最先执行***********"); } }); for(int i=0;i<3;i++){ Runnable runnable = new Runnable(){ publicvoid run(){ try { Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候"); cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行 Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候"); cb.await(); //这里CyclicBarrier对象又可以重用 Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候"); cb.await(); } catch (Exception e) { e.printStackTrace(); } } }; service.execute(runnable); } service.shutdown(); } }
另外,其还有一些其他方法
方法摘要 | |
---|---|
int | await() 在所有 参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。 |
int | await(long timeout, TimeUnit unit) 在所有 参与者都已经在此屏障上调用 await 方法之前,将一直等待。 |
int | getNumberWaiting() 返回当前在屏障处等待的参与者数目。 |
int | getParties() 返回要求启动此 barrier 的参与者数目。 |
boolean | isBroken() 查询此屏障是否处于损坏状态。 |
void | reset() 将屏障重置为其初始状态。 |
既然提到了CyclicBarrier,就不得不提到另一个相似功能的工具类:CountDownLatch
CyclicBarrier是一个栅栏,其是将走到await()方法的线程进行拦截,直到等待全部的线程走到这个栅栏。
CountDownLatch是一个计数器,其是线程走到await()方法时,进行等待计数,将在计数到达指定值时才继续往下走。
public class CountDownLatchTest {
static CountDownLatch c = new CountDownLatch(2);
public staticvoid main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
publicvoid run() {
System.out.println(1);
//进行计数,计数-1
c.countDown();
System.out.println(2);
//进行计数,计数-1
c.countDown();
}
}).start();
//主线程等待计数
c.await();
System.out.println("3");
}
}
CountDownLatch当计数到0时,计数无法被重置;CyclicBarrier计数达到指定值时,计数置为0重新开始。
CountDownLatch每次调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响;
CyclicBarrier只有一个await()方法,调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞。
主要方法
public CountDownLatch(int count);
publicvoid countDown();
publicvoid await() throws InterruptedException
相关文章推荐
- java多线程-concurrent-CountDownLatch和CyclicBarrier
- 【java】多线程控制(一)---Semaphore、Exchanger、CyclicBarrier、CountDownLatch
- java多线程 栅栏(CyclicBarrier) 和 多线程辅助类 CountDownLatch
- Java多线程——其他工具类CyclicBarrier、CountDownLatch和Exchange
- java多线程并发(一)Semaphore,volatile,synchronized ,Lock, CyclicBarrier和CountDownLatch
- Java中的CyclicBarrier和CountDownLatch
- 多线程系列之Semaphore、CyclicBarrier、CountDownLatch
- Java多线程之CyclicBarrier、Future和FutureTask
- [Java并发包学习五]CountDownLatch和CyclicBarrier介绍
- Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例
- Java并发工具类CountDownLatch和CyclicBarrier
- Java多线程之CyclicBarrier
- java多线程问题之同步器CyclicBarrier
- java多线程问题之同步器CyclicBarrier
- 多线程CyclicBarrier与CountDownLatch使用示例
- java 中间件学习4-CountDownLatch、CyclicBarrier、Future和FutureTask
- java多线程之CyclicBarrier简单用法
- Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask
- Java基础:多线程之CountDownLatch、CyclicBarrier、Exchanger
- Java多线程之CyclicBarrier