CyclicBarrier和CountDownLatch的区别

CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。
CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.
而CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.

CountDownLatchCyclicBarrier
减计数方式加计数方式
计算为0时释放所有等待的线程计数达到指定值时释放所有等待线程
计数为0时,无法重置计数达到指定值时,计数置为0重新开始
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞
不可重复利用可重复利用
下面这3个方法是CountDownLatch类中最重要的方法:
public void await() throws InterruptedException { };   //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行  
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行  
public void countDown() { };  //将count值减1 
一个关于 CountDownLatch的简单demo:

package Thread;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {

	public static void main(String[] args) {
		//5为计数值
		CountDownLatch countDownLatch = new CountDownLatch(5);
		for (int i = 1; i < 6; i++) {
			new Thread(new readNum(i, countDownLatch)).start();
		}
		try {
			//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
			//此时是主线程被挂起,等5个子线程执行完成后主线程接着执行
			countDownLatch.await();
			//让主线程睡1000ms让结果更明显
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("主线程执行结束。。。。");
	}

	static class readNum implements Runnable {
		private int id;
		private CountDownLatch latch;

		public readNum(int id, CountDownLatch latch) {
			this.id = id;
			this.latch = latch;
		}

		@Override
		public void run() {
			synchronized (this) {
				System.out.println("id:" + id);
				//调用countDown()方法,将countDownLatch值减1
				latch.countDown();
				System.out.println("线程组任务" + id + "结束,其他任务继续");
				try {
					//线程睡100ms,让结果更明显
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}  
}
执行结果如下:

id:2
线程组任务2结束,其他任务继续
id:3
线程组任务3结束,其他任务继续
id:5
id:4
线程组任务4结束,其他任务继续
id:1
线程组任务5结束,其他任务继续
线程组任务1结束,其他任务继续
线程执行结束。。。。
可以看出来,只有主线程调用了await()方法并且阻塞,即就是只有主线程等待其他的5个子线程执行完成,主线程在接着向下执行

一个关于CyclicBarrier的简单demo:

package Thread;

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

public class CyclicBarrierTest2 {

	public static void main(String[] args) {
		//定义6个线程需要等待
		CyclicBarrier cyclicBarrier = new CyclicBarrier(6);
		for (int i = 0; i < 5; i++) {
			new Thread(new readNum(i, cyclicBarrier)).start();
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			//主线程睡1000ms,等子线程全部执行完成后,主线程在调用await()方法,
			//将count值加1,此时cyclicBarrier的count值已经等于6,全部的线程开始接着向下执行
			cyclicBarrier.await();
		} catch (InterruptedException | BrokenBarrierException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		//主线程在睡1000ms,等5个子线程都打印完成,在接着向下执行
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("主线程执行结束。。。。");
	}

	static class readNum implements Runnable {
		private int id;
		private CyclicBarrier barrier;

		public readNum(int id, CyclicBarrier barrier) {
			this.id = id;
			this.barrier = barrier;
		}

		@Override
		public void run() {
			 {
				System.out.println("id:" + id);
					try {
						//每一个线程进来调用await()方法,将barrier的count值加1
						barrier.await();
						System.out.println("线程组任务" + id + "结束,其他任务继续");
					}
					 catch (BrokenBarrierException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}  
}
运行结果如下所示:

id:1
id:2
id:0
id:3
id:4
线程组任务1结束,其他任务继续
线程组任务0结束,其他任务继续
线程组任务4结束,其他任务继续
线程组任务2结束,其他任务继续
线程组任务3结束,其他任务继续
主线程执行结束。。。。
可以看出来,主线程和每个子线程都调用了await()方法,他们之间是相互等待的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值