JUC--CountDownLatch 野性酷女 2023-01-13 01:53 158阅读 0赞 原文网址:[JUC--CountDownLatch\_IT利刃出鞘的博客-CSDN博客][JUC--CountDownLatch_IT_-CSDN] # 其他网址 # [Java并发编程 闭锁:FutureTask、CountDownLatch、Semaphore常见使用方法\_APlus-CSDN博客][Java_ _FutureTask_CountDownLatch_Semaphore_APlus-CSDN] [CountDownLatch、Future、CyclicBarrier - 循环屏障 和 Semaphore - 信号量-CSDN博客][CountDownLatch_Future_CyclicBarrier - _ _ Semaphore - _-CSDN] 《Java并发编程之美》=> 10.1 CountDownLatch 原理剖析 # 简介 # **说明** > 在曰常开发中经常会遇到需要在主线程中开启多个线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后再进行汇总的场景。 > > 在CountDonLatch出现之前一般都使用线程的join()方法来实现这一点,但是join方法不够灵活,两者的对比如下: > > <table style="width:500px;"> > <tbody> > <tr> > <td style="width:128px;"><strong>项</strong></td> > <td style="width:140px;"><strong>CountDonLatch</strong></td> > <td style="width:231px;"><strong>join()</strong></td> > </tr> > <tr> > <td style="width:128px;">是否适用于线程池</td> > <td style="width:140px;">适用。</td> > <td style="width:231px;"> <p>不适用。</p> <p>使用线程池一般是直接添加Runable到线程池,这时没有办法再调用线程的join方法了。</p> </td> > </tr> > <tr> > <td style="width:128px;">调用时机</td> > <td style="width:140px;">允许子线程运行完毕或者在运行中递减计数。</td> > <td style="width:231px;">只能等待线程运行完毕。</td> > </tr> > </tbody> > </table> **方法** > <table> > <thead> > <tr> > <th style="width:306px;">方法名</th> > <th>解释</th> > </tr> > </thead> > <tbody> > <tr> > <td style="width:306px;">void countDown()</td> > <td>计数器减1</td> > </tr> > <tr> > <td style="width:306px;">long getCount()</td> > <td>返回当前计数值</td> > </tr> > <tr> > <td style="width:306px;">void await()</td> > <td>当前线程阻塞,直到该计数器为0后才能继续执行</td> > </tr> > <tr> > <td style="width:306px;">boolean await(long timeout, TimeUnit unit)</td> > <td>与上述await()类似,只不过可以设置等待时间,如果在规定时间内计数器的值依然大于0,则继续执行</td> > </tr> > </tbody> > </table> # 实例 # **简介** > 描述:创建两个线程,主流程里等待这两个线程都结束,才往下进行。 **代码** > package org.example.a; > > import java.util.concurrent.CountDownLatch; > > public class Demo { > // 创建一个CountDownLatch实例 > private static volatile java.util.concurrent.CountDownLatch countDownLatch = new CountDownLatch(2); > > public static void main(String[] args) throws InterruptedException { > Thread threadOne = new Thread(new Runnable() { > @Override > public void run() { > try { > Thread.sleep(1000); > System.out.println("子线程1结束!"); > } catch (InterruptedException e) { > e.printStackTrace(); > } finally { > countDownLatch.countDown(); > } > } > }); > Thread threadTwo = new Thread(new Runnable() { > @Override > public void run() { > try { > Thread.sleep(1000); > System.out.println("子线程2结束!"); > } catch (InterruptedException e) { > e.printStackTrace(); > } finally { > countDownLatch.countDown(); > } > } > }); > // 启动子线程 > threadOne.start(); > threadTwo.start(); > System.out.println("等待所有子线程结束---"); > // 等待子线程执行完毕,返回 > countDownLatch.await(); > System.out.println("所有子线程结束!"); > } > } **测试** > 等待所有子线程结束--- > 子线程2结束! > 子线程1结束! > 所有子线程结束! # 包装 # **其他网址** > [Netty实现同步“请求-响应”的同步通信机制 - SegmentFault 思否][Netty_-_ - SegmentFault] **描述** > 上边的实例仅仅是等待结束,没有传递结果,本处将CountdownLatch包装一下,让它传递结果。 ## 单个结果 ## **包装类** > package org.example.a; > > import java.util.concurrent.CountDownLatch; > import java.util.concurrent.TimeUnit; > > public class SynchroniseUtil<T>{ > private final CountDownLatch countDownLatch = new CountDownLatch(1); > > private T result; > > public T get() throws InterruptedException{ > countDownLatch.await(); > return this.result; > } > > public T get(long timeout, TimeUnit timeUnit) throws Exception{ > if (countDownLatch.await(timeout, timeUnit)) { > return this.result; > } else { > throw new RuntimeException("超时"); > } > } > > public void setResult(T result) { > this.result = result; > countDownLatch.countDown(); > } > } **测试类** > package org.example.a; > > public class Demo { > public static void main(String[] args) throws InterruptedException { > SynchroniseUtil<String> synchroniseUtil = new SynchroniseUtil<>(); > Thread threadOne = new Thread(new Runnable() { > @Override > public void run() { > try { > Thread.sleep(1000); > System.out.println("子线程1结束!"); > } catch (InterruptedException e) { > e.printStackTrace(); > } finally { > synchroniseUtil.setResult("线程1执行成功"); > } > } > }); > > // 启动子线程 > threadOne.start(); > System.out.println("等待所有子线程结束---"); > // 等待子线程执行完毕,返回 > String result = synchroniseUtil.get(); > System.out.println("所有子线程结束!"); > System.out.println("返回结果:" + result); > } > } **测试** > 等待所有子线程结束--- > 子线程1结束! > 所有子线程结束! > 返回结果:线程1执行成功 ## 多个结果 ## [JUC--CountDownLatch_IT_-CSDN]: https://knife.blog.csdn.net/article/details/115723973 [Java_ _FutureTask_CountDownLatch_Semaphore_APlus-CSDN]: https://blog.csdn.net/abc123lzf/article/details/80307976 [CountDownLatch_Future_CyclicBarrier - _ _ Semaphore - _-CSDN]: https://blog.csdn.net/a906998248/article/details/48469649 [Netty_-_ - SegmentFault]: https://segmentfault.com/a/1190000020507086
还没有评论,来说两句吧...