码迷,mamicode.com
首页 > 其他好文 > 详细

CyclicBarrier和CountDownLatch的区别

时间:2018-11-05 22:24:28      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:try   hex   cti   get   计时   dex   exec   结果   一个   

 CountDownLatch

Countdownlatch是一个同步工具类;用来协调多个线程之间的同步;

这个工具通常用来控制线程等待;它可以让某一个线程等待知道倒计时结束,在开始执行;

CountDownLatch的两种用法:

1. 某一线程在开始运行前等待n个线程执行完毕;将CountDownLatch的计数器初始化为n:new CountDownLatch(n);每当一个任务线程执行完毕,就将计数器减1,CountDownLatch.Countdown;当计数器的值变为0时;在CountDownLatch上await()的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕;

2. 实现多个线程开始执行任务的最大并行性;注意是并行性;而不是并发性;强调的是多个线程在某一时刻同时执行,类似于赛跑;将多个线程放到起点;等待发令枪响;然后同时开跑;做法是初始化一个共享的CountDownLatch对象;将其计数器初始化为1:new CountdownLatch(1);多个线程在开始执行任务前首先CountDownLatch.await(),当主线程调用countdownl时,计数器变为0;多个线程同时被唤醒;

package com.practice.test;

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

public class CountDownLatchExample1 {
    public static final int threadCount = 550;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService threadpool = Executors.newFixedThreadPool(300);
        final CountDownLatch cl = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            final int threadnum = i;
            threadpool.execute(() -> {
                try {
                    test(threadnum);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    cl.countDown();
                }
            });
        }
        cl.await();
        threadpool.shutdown();
        System.out.println("finish");
    }

    public static void test(int threadnum) throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("threadnum" + threadnum);
        Thread.sleep(1000);
    }

}

 

3. Countdownlatch的不足

Countdownlatch是一次性的,计数器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后,他不能再次被使用

CyclicBarrier

CyclicBarrier和CountDownLatch非常类似,他也可以实现线程间的技术等待,但是它的功能比CountDownLatch更加强大和复杂。主要应用场景和CountDownLatch类似

CyclicBarrier的字面意思是可循环使用的屏障,它要做的事情是,让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法时CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障。然后当前线程被阻塞;

package com.practice.test;

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

public class CyclicBarrierExample2 {
    private static final int threadcount = 550;
    private static final CyclicBarrier cyb = new CyclicBarrier(5);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService threadpool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < threadcount; i++) {
            final int num = i;
            Thread.sleep(1000);
            threadpool.execute(() -> {
                try {
                    try {
                        test(num);
                    } catch (TimeoutException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            });
        }
        threadpool.shutdown();
    }

    public static void test(int threadnum) throws InterruptedException, BrokenBarrierException, TimeoutException {
        System.out.println("threadnum" + threadnum + "is ready");
        try {
        cyb.await(2000, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            System.out.println("CyclicBarrier");
        }
        System.out.println("threadnum" + threadnum + "isFinish");
    }
}

 

CyclicBarrier的应用场景

CyclicBarrier可以用于多线程计算数据,最后合并结果的应用场景。比如我们用一个Excel保存了用户所有银行流水,每个Sheet保存每一个账户近一年的每一笔银行流水,现在需要统计用户的日均银行流水,先用多线程处理每个sheet里的银行流水,都执行完之后,得到每个sheet的日均银行流水,最后,使用barrierAction用这些线程的计算结果,计算出整个Excel的日均银行流水;

CyclicBarrier(int parties,Runnable BarrierAction),在线程到达屏障时,优先执行BarrierAction,方便处理更复杂的业务场景;

package com.practice.test;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cyl = new CyclicBarrier(5, () -> {
            System.out.println("线程组执行结束");

        });
        for (int i = 0; i < 5; i++) {
            new Thread(new Readnum(i, cyl)).start();
        }
    }

    static class Readnum implements Runnable {
        private int id;
        private CyclicBarrier cdl;

        public Readnum(int id, CyclicBarrier cdl) {
            super();
            this.id = id;
            this.cdl = cdl;
        }

        @Override
        public void run() {
            synchronized (this) {
                System.out.println(Thread.currentThread().getName() + "id");
                try {
                    cdl.await();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + id + "结束了");

            }
        }
    }
}

 

CyclicBarrier和CountDownLatch的区别

技术分享图片

CountDownLatch是计数器,只能使用一次,而CyclicBarrier的计数器提供reset功能,可以多次使用,

JavaDoc中的定义:

CountDownLatch:一个或者多个线程,等待其他线程完成某件事情之后,等待其他多个线程完成某件事情之后才能执行;

CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行;

对于CountDownLatch来说,重点是一个线程(多个线程)等待”,而其他的N个线程在完成”某件事情“之后,可以终止,也可以等待,而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须等待;

CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都要到达,阀门才能打开,然后继续执行;

 

文章参考自:

https://github.com/Snailclimb

https://blog.csdn.net/tolcf/article/details/50925145?utm_source=blogxgwz0

CyclicBarrier和CountDownLatch的区别

标签:try   hex   cti   get   计时   dex   exec   结果   一个   

原文地址:https://www.cnblogs.com/yjxs/p/9911903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!