CountDownLatch和CyclicBarrier的区别

  在网上看到很多人对于CountDownLatch和CyclicBarrier的区别简单理解为CountDownLatch是一次性的,而CyclicBarrier在调用reset之后还可以继续使用。那如果只是这么简单的话,我觉得CyclicBarrier简单命名为ResetableCountDownLatch好了,显然不是的。

CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

CountDownLatch:一种同步帮助,允许一个或多个线程等待直到在其他线程中执行的一组操作完成。


CyclicBarrier: A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

CyclicBarrier:一种同步辅助装置,允许一组线程彼此等待,以达到共同的阻挡点。

总结和个人理解:
CountDownLatch:一个线程(或者多个),等待另外一个或N个线程完成某个事情之后才能执行。   
CyclicBarrier:N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成所有的线程都必须等待。
即CountDownLatch是一个或N个线程在等待“另一类的”一个,而CyclicBarrier是“一类”中的N个相互等待。

代码理解:

CountDownLatch:

package com.test1.zookeeper;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *@author WHD
 *data 2017年4月9日
 */
public class Test2 {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
	ExecutorService executeService = Executors.newFixedThreadPool(5);
	final CountDownLatch cd = new CountDownLatch(5);
	final CyclicBarrier  cb = new CyclicBarrier(5);       
	for(int i =0;i<5;i++){
		System.out.println("i:"+i);
		executeService.execute(new Runnable(){
			public void run(){
				try {
					//阻塞子线程,直到CountDownLatch计数器减为0
					cd.await();
					//cb.await();
					System.out.println("线程名称"+Thread.currentThread().getId());
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		cd.countDown();
		System.out.println("hello countdownlatch……");
	}
	
}
}
这个个人理解就是子线程在等待CountDownLatch这个计数器,或者说子线程在等待驱动Main方法的线程完成它的任务!

CyclicBarrier:

package com.test1.zookeeper;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *@author WHD
 *data 2017年4月9日
 */
public class Test2 {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
	ExecutorService executeService = Executors.newFixedThreadPool(5);
	final CyclicBarrier  cb = new CyclicBarrier(5);       
	for(int i =0;i<5;i++){
		System.out.println("i:"+i);
		executeService.execute(new Runnable(){
			public void run(){
				try {
					//五个子线程相互等待,等都到齐了才开始运行!
					cb.await();
					System.out.println("线程名称"+Thread.currentThread().getId());
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		System.out.println("hello countdownlatch……");
	}
	
}
}

参考文章:

http://blog.youkuaiyun.com/kjfcpua/article/details/7300286
http://blog.youkuaiyun.com/shihuacai/article/details/8856407

`CountDownLatch` `CyclicBarrier` 是 Java 中用于控制线程同步的两个工具类,它们都位于 `java.util.concurrent` 包中,但它们的用途行为有显著区别: ### 1. **用途不同** - **CountDownLatch** 适用于一个或多个线程等待其他线程完成一系列操作后才能继续执行的场景。它通过一个计数器来控制线程的等待,计数器初始化为一个正整数,每次调用 `countDown()` 方法会减少计数器的值,当计数器变为 0 时,所有等待的线程被释放。 - **CyclicBarrier** 适用于多个线程相互等待,直到所有线程都到达一个屏障点后再一起继续执行。它允许一组线程互相等待,直到所有线程都到达某个公共屏障点。 ### 2. **是否可重用** - **CountDownLatch** 不可重用,计数器一旦减到 0,就不能再被重置。 - **CyclicBarrier** 可以重复使用,当所有线程到达屏障点后,计数器会被重置为初始值,可以再次使用。 ### 3. **线程阻塞方式** - **CountDownLatch** 线程通过调用 `await()` 方法等待计数器变为 0,而其他线程通过调用 `countDown()` 来减少计数器。 - **CyclicBarrier** 每个线程调用 `await()` 后会进入等待状态,直到所有线程都调用 `await()`,此时屏障被解除,所有线程继续执行。 ### 4. **异常处理** - **CountDownLatch** 如果某个等待线程被中断,不会影响其他线程的计数。 - **CyclicBarrier** 如果某个线程在等待时被中断或超时,会触发 `BrokenBarrierException`,并且屏障会被打破,其他线程也会收到异常。 ### 示例代码 #### CountDownLatch 示例 ```java import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(3); for (int i = 1; i <= 3; i++) { final int threadId = i; new Thread(() -> { System.out.println("Thread " + threadId + " is working..."); latch.countDown(); // 完成任务后计数减一 }).start(); } latch.await(); // 主线程等待所有子线程完成 System.out.println("All threads have finished their work."); } } ``` #### CyclicBarrier 示例 ```java import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierExample { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(3, () -> { System.out.println("All threads have reached the barrier."); }); for (int i = 1; i <= 3; i++) { final int threadId = i; new Thread(() -> { try { System.out.println("Thread " + threadId + " is working..."); barrier.await(); // 等待所有线程到达屏障 } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } } ``` ### 总结 - `CountDownLatch` 是 **一次性** 的,适合一个线程等待多个任务完成。 - `CyclicBarrier` 是 **可重复使用** 的,适合多个线程相互等待,直到所有线程都到达某个屏障点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值