CountDownLatch和CyclicBarrier理论上的区别
作为理论型的Java选手,在秋招的疯狂背概念的时候,一直很困惑和
有什么区别,api上的区别是能理解的,用法上的区别也是可以理解的,比如说:
CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。
但是,为什么大部分人的博客后面都搞一句引用值Java Doc
的话,是,Java Doc
很权威,但我实在理解不了,多个线程等待多个其他线程和多个线程相互等待有什么区别
CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行;
CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。
Api角度透析
CountDownLatch
两个核心api
等待对象
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }
需求方法
public void countDown() { sync.releaseShared(1); }
CyclicBarrier一个核心api
等待对象
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException { return dowait(true, unit.toNanos(timeout));}
从api就能察觉到两者的区别,CountDownLatch
的两个api可以在不同的地方调用,这也就决定有等待的一方和进行操作的一方,而CycliBarrier
的一个api
就显得只能在一方操作。
回归到提出的疑问
CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行;
CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。
上面描述的CountDownLatch描述中出现的一个或者多个线程是下图中右侧调用await()
等待左侧多个线程完成特定事件(acquire
),将右侧的多个线程比作是乘坐火箭的乘客,左侧线程比做成控制台的操作人员们可能会是个合适的比喻,乘客都上火箭后,等待操作台的工作人员们检测设备,所有设备正常后,发射火箭。
对比来看CyclicBarrier,只有一个api,也像上面所说,只能让这N个线程相互进行等待,一通通过障碍点,可以比作大巴车,车满就发车(现实里车不满也会发),至于出站的时候通不通知站台进行报备就要看站台的大小(是否需要指定构造函数中的Runnable),大巴车每天发很多回,不像火箭发出去就回不来。