• CyclicBarrier和CountDownLatch的区别


     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

  • 相关阅读:
    elasticsearch(0.90.10)安装配置+超多插件!!
    【架构】基于Nutch+Hadoop+Hbase+ElasticSearch的网络爬虫及搜索引擎
    Elasticsearch(1.1.1)基础教程pdf
    hadoop1.2.1+hbase0.94.11+nutch2.2.1+elasticsearch0.90.5安装配置攻略
    安装和使用 Elasticsearch(1.1.1)+marvel插件、Kibana插件
    nutch2.1+mysql+elasticsearch整合linux单机部署
    Nutch 快速入门(Nutch 2.2.1+Hbase+Solr)
    Linux中VMware虚拟机增加磁盘空间的扩容操作
    java8使用stream的collect进行list转map注意事项
    Java 8 指南
  • 原文地址:https://www.cnblogs.com/yjxs/p/9911903.html
Copyright © 2020-2023  润新知