CountDownLatch用法详解

这篇具有很好参考价值的文章主要介绍了CountDownLatch用法详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

CountDownLatch用法详解

深入理解CountDownLatch计数器

CountDownLatch使用场景

线程计数器 用于线程执行任务,计数 等待线程结束

用法一: 等待所有的事情都做完


        //程序计数器
        CountDownLatch countDownLatch = new CountDownLatch(10000);

        //2个线程
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        AtomicInteger count = new AtomicInteger(0);
        for (int i = 0; i < 10000; i++) {

            executorService.submit(() -> {
                count.getAndIncrement();//自增
                System.out.println(Thread.currentThread().getName() + " : " + count.get());
                countDownLatch.countDown();
            });
        }


        //线程池 等待10s
        executorService.awaitTermination(10, TimeUnit.SECONDS);

        //关闭线程 其实是将线程状态设置为中断标志  必须等待所有线程处理完任务,才能完全关闭
        executorService.shutdown();

        //必须等待两个线程执行完   会一直等待下去,当然也可以设置指定时间等待超时 await(timeout);
        countDownLatch.await();


    }

始终是2个线程在做事情,等2个线程做完事情才会停止下来。

用法二:假设2个线程做事情,刚开始并行做事情,等一个执行完成之后,另一个才能执行(实际还是计数)



        //程序计数器
        CountDownLatch countDownLatch = new CountDownLatch(1);

        Thread thread1 =new Thread(()->{

                System.out.println(" ---------------- 1  准备 ---------------- ");
                try {
                    countDownLatch.await();
                    System.out.println(" ---------------- 1  finsh  ---------------- ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });
        thread1.start();

        Thread thread2 = new Thread(() -> {


                System.out.println(" ---------------- 2  准备 ---------------- ");
                try {
                    Thread.sleep(1_000);
                    System.out.println(" ---------------- 异步做事情  ---------------- ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    countDownLatch.countDown();
                }
        });
        thread2.start();


        //main 在等main 结束  死循环
        Thread.currentThread().join();

刚开始一起在准备状态,然后分开做事情

CountDownLatch用法详解

用法三:退出条件

中断一个线程 count 到0

        //程序计数器
        CountDownLatch countDownLatch = new CountDownLatch(1);
        Thread thread = Thread.currentThread();
        Thread thread1 = new Thread(() -> {
            try {
             Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 1 中断条件1
		    countDownLatch.countDown();

        });

        thread1.start();

        countDownLatch.await();
       

        System.out.println(" ----------------- ");

    }

等待时间中断

        //程序计数器
        CountDownLatch countDownLatch = new CountDownLatch(1);
        Thread thread = Thread.currentThread();
        Thread thread1 = new Thread(() -> {
            try {
             Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();

     
        //2 中断条件3
        countDownLatch.await(5, TimeUnit.SECONDS);

        System.out.println(" ----------------- ");

    }

就中断条件而言: 当前还可以父线程中断


        //程序计数器
       
    
        Thread thread1 = new Thread(() -> {
            try {
             Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        
            // 中断条件3
            thread.interrupt();
        });

        thread1.start();

   

        System.out.println(" ----------------- ");

用法四: 封装结束完后通知事件

封装结束完后通知事件 参考 CyclicBarrier 通知

public class CountDownLatchTest4 extends CountDownLatch {

    private Runnable runnable;

    public CountDownLatchTest4(int count, Runnable runnable) {
        super(count);
        this.runnable = runnable;
    }

    @Override
    public void countDown() {
        super.countDown();
        if (super.getCount()==0){
            runnable.run();
        }
    }

    public static void main(String[] args) throws InterruptedException {


        //程序计数器
        CountDownLatchTest4 countDownLatch = new CountDownLatchTest4(1,()->{

            System.out.println(" 计数结束 .... ");
        });

        Thread thread1 = new Thread(() -> {
            try {
                Thread.sleep(2_000);
                countDownLatch.countDown();
                System.out.println(" thread 1 do something ");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1_000);
                System.out.println(" thread 2 do something ");
                countDownLatch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();

        countDownLatch.await();

        System.out.println("  -----------------  main 结束 ----------------- ");

    }
}

可以看到运行结束,通知事件
CountDownLatch用法详解

自定义计数器

当然我们也可以实现自己的计数器


/**
 * 自定义 CountDown 计数器
 */
public class CountDown {


    //计数器
    private int count = 0;
    private final int total;

    public CountDown(int total) {
        this.total = total;
    }


    public void countDown() {
        synchronized (this) {
            this.count++;
            //锁住 ++ 通知其他线程
            this.notifyAll();
        }
    }


    public void aWait() throws InterruptedException {
        synchronized (this) {
            while (total != count) {
                //不等于 则 继续等待
                this.wait();
            }
        }
    }
}

测试


        CountDown countDown = new CountDown( 5);

        System.out.println(" 准备多线程处理任务 ");

        IntStream.rangeClosed(1, 5).forEach(x -> {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(" 线程开始 -----  " + Thread.currentThread().getName());
                countDown.countDown();
            }, x + "").start();

        });

        try {
            countDown.aWait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(" 准备多线程处理任务 结束 ");
        System.out.println(" ---------------------- ");
        System.out.println(" 结束 mian ---------- ");
    }

测试结果

CountDownLatch用法详解

最后

CountDownLatch 可以用来计数,可以测试任务是否执行结束
也可以用来停止一个线程,也可以用来线程运行结束完后通知事件,彼此工作的线程互相独立不关心。文章来源地址https://www.toymoban.com/news/detail-418629.html

到了这里,关于CountDownLatch用法详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 巧用CountDownLatch实现多线程并行工作

    【前言】       CountDownLatch 是JDK提供的一个同步工具,它可以让一个或多个线程挂起等待,一直等到其他线程执行完成才会继续执行。常用方法有 countDown 方法和 await 方法, CountDownLatch 在初始化时,需要指定一个整数n作为计数器。当调用 countDown 方法时,计数器会被减1;

    2024年02月13日
    浏览(39)
  • 【Java基础】线程同步类 CountDownLatch

    ​ 关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 正好今天项目中用到了CountDownLatch,那我们正好总结一下,通过本文你可以学到什么是CountDownLatch及其原理,

    2024年02月12日
    浏览(47)
  • ListenableFuture和countdownlatch使用example

    ListenableFuture可以允许你注册回调方法(callbacks),在运算(多线程执行)完成的时候进行调用, 或者在运算(多线程执行)完成后立即执行

    2024年02月07日
    浏览(44)
  • CountDownLatch倒计时器源码解读与使用

    🏷️ 个人主页 :牵着猫散步的鼠鼠  🏷️ 系列专栏 :Java全栈-专栏 🏷️ 个人学习笔记,若有缺误,欢迎评论区指正   目录 1. 前言 2. CountDownLatch有什么用 3. CountDownLatch底层原理 3.1. countDown()方法 3.2. await()方法 4. CountDownLatch的基本使用 5. 总结 在很多的面经中都看到过提问

    2024年04月22日
    浏览(31)
  • 工作记录----CountDownLatch(特别好用的一个工具类)

    CountDownLatch 是 Java 并发包中的一个同步工具类,它可以让一个或多个线程等待其他线程完成操作。它的核心思想是,一个线程(或多个线程)在执行某个任务时,可以通过它等待其他线程的信号,直到其他线程的任务完成才继续执行。用于实现线程间的等待和通知机制。 主要

    2024年02月03日
    浏览(34)
  • CountDownLatch介绍和使用【Java多线程必备】

    点击   Mr.绵羊的知识星球  解锁更多优质文章。 目录 一、介绍 二、特性 三、实现原理 四、适用场景 五、注意事项 六、实际应用     CountDownLatch 是 Java 中的一个并发工具类,用于协调多个线程之间的同步。其作用是让某一个线程等待多个线程的操作完成之后再执行。它可

    2024年02月05日
    浏览(50)
  • Java并发工具CountDownLatch的使用和原理

    CountDownLatch 允许一个或多个线程等待其他线程完成操作。 假如有这样一个需求:我们需要解析一个 Excel 里多个 sheet 的数据,此时可以考虑使用多线程,每个线程解析一个 sheet 里的数据,等到所有的 sheet 都解析完之后,程序需要提示解析完成。在这个需求中,要实现主线程

    2024年02月16日
    浏览(33)
  • keycloak~CountDownLatch在keycloak中的使用

    在Java中, CountDownLatch 是一个线程同步的辅助类,用于等待其他线程完成操作。如果 CountDownLatch 实例被丢失或无法访问,可能会导致无法正常使用该对象。这可能会导致等待线程永远处于等待状态,无法继续执行。 如果意外丢失了 CountDownLatch 对象,你可以尝试以下方法进行

    2024年02月09日
    浏览(40)
  • 8.18信号量Semaphore和CountDownLatch

    一 .Semaphore: 1.Semaphore是一个计数器(变量),描述可用资源的个数,用来判断是否有临界资源可用. 2.临界资源:多个进程或线程并发执行的实体可以公共使用到的资源. 3.pv操作:p操作(accquire(申请))表示计数器减一,v操作(release(释放))表示计数器加一. 4.锁是特殊的信号量,二元信号量.

    2024年02月14日
    浏览(32)
  • CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽

            我设置了CountDownLatch对线程的协作做出了一些限制,但是我发现运行一段时间以后便发现定时任务不运行了。 具体代码: 报错以后定时任务不运行了   打印线程日志发现定时任务的线程在第86行代码停着不动了。 正常的线程日志应该是这样的。 查看第86行代码,

    2024年04月24日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包