CyclicBarrier和CountDownLatch区别

来源:互联网 发布:java缓存和中间件 编辑:程序博客网 时间:2024/05/29 11:42

这两天写多线程时,用到了CyclicBarrier,下意识的认为CyclicBarrier和CountDownLatch作用很像,就翻阅资料查了一下,说一下他们的区别吧


CyclicBarrier和CountDownLatch 都位于java.util.concurrent 这个包下


CountDownLatchCyclicBarrier减计数方式加计数方式计算为0时释放所有等待的线程计数达到指定值时释放所有等待线程计数为0时,无法重置计数达到指定值时,计数置为0重新开始调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞不可重复利用可重复利用
一、CountDownLatch用法


CountDownLatch类只提供了一个构造器:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. public CountDownLatch(int count) {  };  //参数count为计数值  

然后下面这3个方法是CountDownLatch类中最重要的方法:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. public void await() throws InterruptedException { };   //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行  
  2. public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行  
  3. public void countDown() { };  //将count值减1  


CountDownLatch, 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

下面举个例子说明:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package main.java.CountDownLatch;  
  2.   
  3. import java.util.concurrent.CountDownLatch;  
  4.   
  5. /** 
  6.  * PROJECT_NAME:downLoad 
  7.  * Author:lucaifang 
  8.  * Date:2016/3/18 
  9.  */  
  10. public class countDownlatchTest {  
  11.     public static void main(String[] args) throws InterruptedException {  
  12.         CountDownLatch countDownLatch = new CountDownLatch(5);  
  13.         for(int i=0;i<5;i++){  
  14.             new Thread(new readNum(i,countDownLatch)).start();  
  15.         }  
  16.         countDownLatch.await();  
  17.         System.out.println("线程执行结束。。。。");  
  18.     }  
  19.   
  20.     static class readNum  implements Runnable{  
  21.         private int id;  
  22.         private CountDownLatch latch;  
  23.         public readNum(int id,CountDownLatch latch){  
  24.             this.id = id;  
  25.             this.latch = latch;  
  26.         }  
  27.         @Override  
  28.         public void run() {  
  29.             synchronized (this){  
  30.                 System.out.println("id:"+id);  
  31.                 latch.countDown();  
  32.                 System.out.println("线程组任务"+id+"结束,其他任务继续");  
  33.             }  
  34.         }  
  35.     }  
  36. }  

输出结果:

id:1
线程组任务1结束,其他任务继续
id:0
线程组任务0结束,其他任务继续
id:2
线程组任务2结束,其他任务继续
id:3
线程组任务3结束,其他任务继续
id:4
线程组任务4结束,其他任务继续
线程执行结束。。。。


线程在countDown()之后,会继续执行自己的任务,而CyclicBarrier会在所有线程任务结束之后,才会进行后续任务,具体可以看下面例子。

二、CyclicBarrier用法

CyclicBarrier提供2个构造器:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. public CyclicBarrier(int parties, Runnable barrierAction) {  
  2. }  
  3.    
  4. public CyclicBarrier(int parties) {  
  5. }  
参数parties指让多少个线程或者任务等待至barrier状态;参数barrierAction为当这些线程都达到barrier状态时会执行的内容。

CyclicBarrier中最重要的方法就是await方法

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. public int await() throws InterruptedException, BrokenBarrierException { };//挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务;  
  2. public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };//让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务  


举例说明

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package main.java.countOff;  
  2.   
  3. import java.util.concurrent.CyclicBarrier;  
  4.   
  5. /** 
  6.  * PROJECT_NAME:downLoad 
  7.  * Author:lucaifang 
  8.  * Date:2016/3/18 
  9.  */  
  10. public class cyclicBarrierTest {  
  11.     public static void main(String[] args) throws InterruptedException {  
  12.         CyclicBarrier cyclicBarrier = new CyclicBarrier(5new Runnable() {  
  13.             @Override  
  14.             public void run() {  
  15.                 System.out.println("线程组执行结束");  
  16.             }  
  17.         });  
  18.         for (int i = 0; i < 5; i++) {  
  19.             new Thread(new readNum(i,cyclicBarrier)).start();  
  20.         }  
  21.         //CyclicBarrier 可以重复利用,  
  22.         // 这个是CountDownLatch做不到的  
  23. //        for (int i = 11; i < 16; i++) {  
  24. //            new Thread(new readNum(i,cyclicBarrier)).start();  
  25. //        }  
  26.     }  
  27.     static class readNum  implements Runnable{  
  28.         private int id;  
  29.         private CyclicBarrier cyc;  
  30.         public readNum(int id,CyclicBarrier cyc){  
  31.             this.id = id;  
  32.             this.cyc = cyc;  
  33.         }  
  34.         @Override  
  35.         public void run() {  
  36.             synchronized (this){  
  37.                 System.out.println("id:"+id);  
  38.                 try {  
  39.                     cyc.await();  
  40.                     System.out.println("线程组任务" + id + "结束,其他任务继续");  
  41.                 } catch (Exception e) {  
  42.                     e.printStackTrace();  
  43.                 }  
  44.             }  
  45.         }  
  46.     }  
  47. }  

输出结果:

id:1
id:2
id:4
id:0
id:3
线程组执行结束
线程组任务3结束,其他任务继续
线程组任务1结束,其他任务继续
线程组任务4结束,其他任务继续
线程组任务0结束,其他任务继续
线程组任务2结束,其他任务继续

0 0
原创粉丝点击