zoukankan      html  css  js  c++  java
  • Java并发编程-JUC-CountDownLatch 倒计数门闩器-等待多线程完成再放行 -一次性使用

    如题 (总结要点 ,看不懂下面有更多解释, 参考书籍《Java并发编程实战》)

    • CountDownLatch 倒计数门闩器
    • 让1-n-1个线程等待主线程完成工作。(Excel的多个Sheet的解析,最终等待解析完毕后;要实现主线程等待所有线程完成sheet解析操作,最简单的就是join )
      常用API
    • CountDownLatch latch = new CountDownLatch(2); // 新建一个倒计数门闩器 ,常用于迫使主线程进入等待 ;设置N个结点 ,n个线程或者步骤
    • latch.countDown(); // 计数器-1
    • latch.await(1000, TimeUnit.MILLISECONDS); //阻塞当前线程(常为主线程),直到计数器变为0
      区分
      • CyclicBarrier循环栅栏,维持最低的并发,让多个线程同时并发执行。每调用一次await()方法都将使阻塞的线程数+1,只有阻塞的线程数达到设定值时屏障才会打开,允许阻塞的所有线程继续执行。

    适用场景总结

    例子一

    • 比如导出一份Excel, 共有10万行, 拆分出10K行 * 10个线程来解析(导入/导出)处理; 主线程来创建(或提交)任务并分配10个新线程来处理;
    • 由于主线程分配完任务后就继续往下执行了, 其他的那10个新的线程还需要等待一段时间; 那这段时间差怎么处理??
    • Excel的多个Sheet的解析,最终等待解析完毕后再进行汇总处理, 主线程需要进行汇总处理, 那么就使用CountDownLatch 倒计数门闩器,来处理就很合理了.

    例子二

    • 需要分别统计 sort_id 为1-1万的某个表的字段数量, 使用多线程处理,调用10个线程并发统计,每个统计%K的范围; 倒计数门闩就很合适, 最后处理完了,主线程再进行处理/封装再返回.
    • 依次类推

    常用api

    //构造器, 参数count为计数值
    public CountDownLatch(int count) {  };  
    
    //调用await()方法的线程会被挂起(一般是主线程),它会等待直到count值为0才继续执行
    public void await() throws InterruptedException { };   
    
    //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
    public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  
    
    //将count值减1
    public void countDown() { };  
    

    1.测试1 简单测试

    
    public class Test03_countdownlatch {
        public static void main(String[] args) {
    
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                     // 睡眠可以开启, Thread.sleep(1000L);
                    System.out.println("hello ");
                }
            };
            Thread thread1 = new Thread(runnable);
            Thread thread2 = new Thread(runnable);
            System.out.println("all thread finish");
        }
    }
    
    

    2. 结果1 : 线程还没有来得及执行完毕,主线程就结束了(JVM关闭了),所以先打印的finish ; 如果子线程数量更多的话, 子线程就不一定能打印完.自己试试! 或者

    all thread finish
    hello 
    hello 
    

    3.测试2 迫使主线程通过子线程的join方法等待当前的子线程执行完毕

     public static void main(String[] args) {
    
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello ");
                }
            };
            Thread thread1 = new Thread(runnable);
            Thread thread2 = new Thread(runnable);
    
            thread1.start();
            thread2.start();
    
            try {
                // 迫使主线程通过join方法等待当前的子线程执行完毕
                thread1.join();
                // 主线程第二次等待
                thread2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("all thread finish");
        }
    

    测试结果2

    hello 
    hello 
    all thread finish
    

    测试3 使用倒计数门闩器

    public static void main(String[] args) {
    
            Runnable runnable = () -> System.out.println("hello ");
            Thread thread1 = new Thread(runnable);
            Thread thread2 = new Thread(runnable);
    
            // 使用倒计数门闩器 ,迫使主线程进入等待 ;设置N个结点 ,n个线程或者步骤都可以
            CountDownLatch latch = new CountDownLatch(2);
            thread1.start();
            latch.countDown();
            thread2.start();
            latch.countDown();
    
            try {
                // 阻塞当前线程,直到计数器变为0; await(long time);也可以带时间!
                latch.await(1000, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("all thread finish");
    
    
        }
    

    测试结果3

    hello 
    hello 
    all thread finish
    
  • 相关阅读:
    基于XML的声明式事务控制
    spring中JdbcTemplate使用
    四种常用的通知类型(xml)
    AOP配置步骤(XML)
    12388. 图论割边
    12389. 割点
    12206. 电缆网络
    12178. 破坏牛棚
    java反射笔记
    java单元测试
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/11365805.html
Copyright © 2011-2022 走看看