CyclicBarrier与CountDownLatch使用
首先查看CyclicBarrier的类图
发现CyclicBarrier并没有超类和实现接口,因此CyclicBarrier只是一个工具类,用以协调线程运行;
与之类似 CountDownLatch也是一个工具类,下面列举了其主要方法
至于两者,对CyclicBarrier比较在意其await方法,而CountDownLatch则比较在意其await与countDown方法
一个简单的小实例:
[code]import java.util.concurrent.*; public class Main{ public static void main(String[] args) { Runnable runnable=new Runnable() { @Override public void run() { System.out.println("当前5个阶段结束"); } }; CyclicBarrier barrier=new CyclicBarrier(3,runnable); CountDownLatch latch=new CountDownLatch(3); for(int i=0;i<3;i++){ MyThread thread=new MyThread(barrier,latch); thread.start(); } try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println("执行完成"); } } static class MyThread extends Thread{ private final CyclicBarrier barrier; private final CountDownLatch latch; //当前每个线程均有5个阶段 private static int PHASE=5; MyThread(CyclicBarrier barrier,CountDownLatch latch) { this.barrier = barrier; this.latch=latch; } @Override public void run() { for(int phase=0;phase<PHASE;phase++){ try { doPhase(phase); barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } latch.countDown(); } protected void doPhase(int phase) throws InterruptedException { System.out.println("当前线程"+this.getName()+"正在执行第"+phase+"阶段"); Thread.sleep(1000); System.out.println("当前线程"+this.getName()+"已结束第"+phase+"阶段"); } } }
输出:
当前线程Thread-0正在执行第0阶段
当前线程Thread-2正在执行第0阶段
当前线程Thread-1正在执行第0阶段
当前线程Thread-0已结束第0阶段
当前线程Thread-1已结束第0阶段
当前线程Thread-2已结束第0阶段
当前5个阶段结束
当前线程Thread-0正在执行第1阶段
当前线程Thread-1正在执行第1阶段
当前线程Thread-2正在执行第1阶段
当前线程Thread-2已结束第1阶段
当前线程Thread-0已结束第1阶段
当前线程Thread-1已结束第1阶段
当前5个阶段结束
当前线程Thread-1正在执行第2阶段
当前线程Thread-0正在执行第2阶段
当前线程Thread-2正在执行第2阶段
当前线程Thread-1已结束第2阶段
当前线程Thread-0已结束第2阶段
当前线程Thread-2已结束第2阶段
当前5个阶段结束
当前线程Thread-2正在执行第3阶段
当前线程Thread-1正在执行第3阶段
当前线程Thread-0正在执行第3阶段
当前线程Thread-0已结束第3阶段
当前线程Thread-1已结束第3阶段
当前线程Thread-2已结束第3阶段
当前5个阶段结束
当前线程Thread-2正在执行第4阶段
当前线程Thread-0正在执行第4阶段
当前线程Thread-1正在执行第4阶段
当前线程Thread-1已结束第4阶段
当前线程Thread-0已结束第4阶段
当前线程Thread-2已结束第4阶段
当前5个阶段结束
执行完成
分析:
CyclicBarrier的用途是创建一个栅栏(从其名字中的Barrier可以看出),构造函数为
[code]CyclicBarrier(int parties, Runnable barrierAction)
意思是在线程A调用它(CyclicBarrier)的await方法后,线程A将会阻塞在这里。直到同一个barrier上的线程调用其await方法达到预先构造函数中int值的次数,所有在此处的线程阻塞将会结束,如果barrierAction不为null,在阻塞结束后将调用该barrierAction的run方法。由其名字中的Cyclic可以看出该类是可重用的,当await的阻塞解除后再次调用await将会再次堵塞;
而
[code]CountDownLatch
称之为闭锁(严格来说这并不是闭锁,只是闭锁的一种实现罢了,但长久以来大家都这么叫了),
其构造函数
[code]CountDownLatch(int count)
说明在某线程调用其await方法后会阻塞,须经其countDown方法调用count次后,阻塞解除,进而继续执行
由于这两者的特性,往往CyclicBarrier常用来实现带有阶段性质的操作或者需要实现某种协议,比如几个家庭决定在6点在麦当劳集合等等,CountDownLatch用以实现确保某些活动知道其他活动都完成后才继续进行,相较两者而言,一些操作使用两者都能实现,因此过于区分两者含义是不正当的;以我而言,两者只存在语义上的差异,功能上一个具有阻塞结束后的操作而另一个没有罢了(实现此操作并不困难);
另外对于InterruptionException这个异常的捕获也很有技巧;
InterruptedException
是一个受检异常,需要显式抛出或者强制处理,当某个方法抛出该异常时,如果你不知道如何处理,请仍旧抛出,如果抛出此异常担心会污染已设计好的接口,请将其装饰为非受检异常(如
IllegalStateException
)再抛出,并给以文档说明;
如下:
try{ //操作 可能抛出InterruptedException }catch(InterruptedException e){ if(knowHowToHandle()){ handleException(); }else if(DoWantTointerface()){ throw new RuntimeException(e); } else { otherOperations(); } }阅读更多
- CountDownLatch和cyclicbarrier的使用
- CountDownLatch、CyclicBarrier、Semaphore共同之处与区别以及各自使用场景
- CountDownLatch与CyclicBarrier的使用与区别
- CountDownLatch 和 CyclicBarrier 的使用场景
- CountDownLatch和CyclicBarrier使用示例
- 你真的理解CountDownLatch与CyclicBarrier使用场景吗?
- CountDownLatch和CyclicBarrier使用及区别
- CountDownLatch和CyclicBarrier的使用和区别
- CountDownLatch和CyclicBarrier的简单使用
- 多线程CyclicBarrier与CountDownLatch使用示例
- CountDownLatch,Semaphore,CyclicBarrier多线程工具类的使用
- CountDownLatch和CyclicBarrier模拟同时并发请求
- CountDownLatch和CyclicBarrier解决运动员赛跑多线程问题
- [Java并发]使用CountDownLatch和CyclicBarrier等待多线程完成
- CyclicBarrier的使用
- Java并发包中CyclicBarrier的工作原理、使用示例
- CountDownLatch、CyclicBarrier和Semaphore
- 浅谈对CountDownLatch和CyclicBarrier的理解
- CountDownLatch 和 CyclicBarrier
- java并发编程中CountDownLatch和CyclicBarrier的使用