CyclicBarrier和CountDownLatch

CountDownLatch

假设有这样一个场景:

两个runner等待起跑, 枪响, 然后观众等待比赛结束. 高声喊出谁是冠军. 同时裁判(主线程)也宣布比赛结束.

class Player implements Runnable{

    private CountDownLatch begin;
    private CountDownLatch end;
    Player(CountDownLatch begin,CountDownLatch end){
        this.begin = begin;
        this.end = end;
    }
    public void run() {    
        try {
            begin.await();//在等待召唤
            System.out.println(Thread.currentThread().getName() + " arrived !");;
            end.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

//观众也在等待比赛结束
class Audience implements Runnable{
    private CountDownLatch end;
    Audience(CountDownLatch end){
        this.end = end;
    }
    public void run() {
        try {
        	end.await();
            System.out.println(Thread.currentThread().getName() + " aha I verify that xx is the champion!");;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class runner {
	public static void main(String[] args) {
		CountDownLatch begin = new CountDownLatch(1);
	       CountDownLatch end = new CountDownLatch(2);

	       for(int i=0; i<2; i++){
	           Thread thread = new Thread(new Player(begin,end));
	           thread.start();
	       }
	       Thread thread3 = new Thread(new Audience(end),"Audience");
	       thread3.start();
	       
	       try{
	           System.out.println("the race begin");
	           //唤醒其他阻塞线程. 可唤醒一个. 有两个runner在竞争. 
	           begin.countDown();
	           
	           //我们在构造函数中添加了参数2,就需要调用 2 次 countDown()  
	           //才能将 end.await() 阻塞的线程唤醒。
	           //当两个runner都调用了countDown() 此时 比赛可以结束了. end.await可以继续执行了. 
	           end.await();
	           System.out.println("the race end");
	       }catch(Exception e){
	            e.printStackTrace();
	       }
	}
}

输出:

the race begin
Thread-1 arrived !
Thread-0 arrived !
Audience aha I verify that xx is the champion!
the race end

 CyclicBarrier

假设有这样一个场景:

y = a(x) + b(x) + c(x) + d(x) + e(x)

想知道y, 必须同时知道a b c d e 的计算结果. 那为了节省时间. 就同时开5个线程去计算 a b c d e,

然后最后计算出结果的人, 把5个结果相加, 就得出y的值了

class TaskThread extends Thread {
    
    CyclicBarrier barrier;
    
    public TaskThread(CyclicBarrier barrier) {
        this.barrier = barrier;
    }
    
    @Override
    public void run() {
        try {
        	System.out.println(getName() + " 计算: 第一步参数(需要1s)");
            Thread.sleep(1000);
            System.out.println(getName() + " 完成: 第一步参数");
            barrier.await();
            
            
            System.out.println(getName() + " 开始: 第二步计算(需要2s)");
            Thread.sleep(2000);
            System.out.println(getName() + " 完成: 第二步参数");
            barrier.await();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public class CyclicBarrierDemo {

	public static void main(String[] args) {
	       int threadNum = 5;
	        CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() {
	            
	            @Override
	            public void run() {
	                System.out.println(Thread.currentThread().getName() + " 计算汇总(最后完成的人汇总!)");
	            }
	        });
	        
	        for(int i = 0; i < threadNum; i++) {
	            new TaskThread(barrier).start();
	        }
	}
}

结果

Thread-0 计算: 第一步参数(需要1s)
Thread-2 计算: 第一步参数(需要1s)
Thread-1 计算: 第一步参数(需要1s)
Thread-3 计算: 第一步参数(需要1s)
Thread-4 计算: 第一步参数(需要1s)
Thread-4 完成: 第一步参数
Thread-2 完成: 第一步参数
Thread-0 完成: 第一步参数
Thread-3 完成: 第一步参数
Thread-1 完成: 第一步参数
Thread-1 计算汇总(最后完成的人汇总!)
Thread-1 开始: 第二步计算(需要2s)
Thread-4 开始: 第二步计算(需要2s)
Thread-0 开始: 第二步计算(需要2s)
Thread-2 开始: 第二步计算(需要2s)
Thread-3 开始: 第二步计算(需要2s)
Thread-4 完成: 第二步参数
Thread-3 完成: 第二步参数
Thread-2 完成: 第二步参数
Thread-1 完成: 第二步参数
Thread-0 完成: 第二步参数
Thread-0 计算汇总(最后完成的人汇总!)

总结

以上是两个应用场景

我们来比较一下CyclicBarrier和CountDownLatch

他们有什么不同:

1.CountDownLatch可以是一个线程, 或者多个线程在等待计数为0, 然后同时触发. 比如:观众和主线程在一起等赛跑结束.

2.CyclicBarrier功能与CountDownLatch类似. 但是他可以循环使用, 比如:运算一次之后, 还可以重新计算. 

3. CyclicBarrier, 所有线程的职责一致. 都是类似减少计数, 达到要求选一个人执行CyclicBarrier预先设定好的任务.

4. CountDownLatch中, 有条件线程, 也有结果线程. 条件线程执行然后减少计数(调用countDown).

   结果线程在条件符合时(计数为0), 将执行自己的逻辑. 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值