Java并发编程同步器CountDownLatch
作者:派大大大星? 发布时间:2022-10-17 18:59:34
CountDownLatch
在日常开发中经常会遇到需要在主线程中开启多个线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后再进行汇总的场景。在 CountDownLatch 出现之前般都使用线程的join()方法来实现这一点,但是 join 方法不够灵活,不能够满足不同场景的需要,所以 JDK 开发组提供了 CountDownLatch
这个类,我们前面介绍的例子使用 CoumtDownLatch
会更优雅。
使用CountDownLatch 的代码如下:
package LockSupportTest;
import java.util.concurrent.CountDownLatch;
public class JoinCountDownLatch {
private static volatile 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("child threadOne over!");
} 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("child threadOne over!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
}
});
threadOne.start();
threadTwo.start();
System.out.println("wait all child thread over!!!");
countDownLatch.await();
System.out.println("all child thread over!");
}
}
在如上代码中,创建了一个 CountDownLatch
实例,因为有两个子线程所以构造函数的传参为2。主线程调用countDownLatch.await()
方法后会被阻塞。子线程执行完毕后调用 countDownLatch.countDown()
方法让 countDownLatch 内部的计数器减1,所有子线程执行完毕并调用 countDown()方法后计数器会变为0,这时候主线程的await()方法才会返回。其实上面的代码还不够优雅,在项目实践中一般都避免直接操作线程,而是使用 ExceutorService线程池来管理,使用ExcsuIwsnise时传递的参数是 Runable 或者 Callable对象,这时候你没有办法直接调用这些线程的join()方法,这就需要选择使用CountDownLatch
了。
将上面的代码修改为:
package LockSupportTest;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class JoinCountDownLatch2 {
private static volatile CountDownLatch countDownLatch = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException{
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("child threadOne over!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
}
});
executorService.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("child threadTwo over!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
}
});
System.out.println("wait all child thread over!!!");
countDownLatch.await();
System.out.println("all child thread over!");
executorService.shutdown();
}
}
最后总结一下CountDownLatch与join()的区别。一个区别是,调用一个子线程的join()方法后,该线程会一直被阻塞直到子线程运行完毕,而 CountDownLatch 则使用计数器来允许子线程运行完毕或者在运行中递减计数,也就是 CountDownLach 可以在子线程运行的任何时候让 await() 方法返回而不一定必须等到线程结東。另外,使用线程池来管理线程时一般都是直接添加 Runable 到线程池,这时候就没有办法再调用线程的 join 方法了,就是说 counDownLatch 相比 join 方法让我们对线程同步有更灵活的控制。
来源:https://juejin.cn/post/7083696858333184008
猜你喜欢
- 目录项目地址示例图片项目结构机器人平滑碰撞其它特性使用打包文件项目文件声明主要代码项目地址https://github.com/SCNU-A
- Spring cloud网关gateway进行websocket路由转发规则配置一、websocket及http路由转发规则配置后端是普通的
- 五丶封装(1)包的概念与创建1>概念在我们的电脑上有许多的文件,我们为了方便管理,大致给它们进行了不同的命名。然后在不同的文件夹下面再
- 什么是零拷贝?零拷贝(英语: Zero-copy)技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。这种技术通常
- 一、JAVA简要概述先说一下java之父,詹姆斯·高斯林这是一个爱喝咖啡而又强大的男人。再来看一下JAVA有多火在TIOBE排行榜上JAVA
- spring @Autowired注解无法注入问题简述在使用spring框架的过程中,常会遇到这种两情况:1、在扫描的包以外使用需要使用ma
- 阅读提示 具有mybatis基础,熟练使用mybatis-plus。概述 我们都知道,mybatis-plus是一个mybatis的增强
- 调用和回调机制在一个应用系统中, 无论使用何种语言开发, 必然存在模块之间的调用, 调用的方式分为几种:1.同步调用同步调用是最基本并且最简
- 目录Spring事件驱动源码实战在项目实际开发过程中,我们有很多这样的业务场景:一个事务中处理完一个业务逻辑后需要跟着处理另外一个业务逻辑,
- 递归方法定义本身调用方法本身的现象叫做递归在这之前我们学的东西:例如StringBuffer.append().append().appen
- java 网络编程java.net 类 InetAddress 此类表示互联网协议 (IP) 地址。 会抛出异常 UnknownHostEx
- 这篇文章主要介绍了Spring Boot项目维护全局json数据代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- package cn.liangjintang.httpproxy;import java.io.BufferedReader;import
- Mybatis注解开发单表操作MyBatis的常用注解Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。我
- SpringBoot如何快速配置数据源;有如下两种方式:通过spring-boot-starter-jdbc快速配置数据源自定义数据源Dat
- 1 . pom.xml添加相关依赖<parent> <groupId>org.spring
- 一、定义登录控制器目录结构代码:1、创建TUser类package com.demo.pojo;import lombok.AllArgsC
- 安装 Tomcat 之前请一定先安装 Java ,然后才能安装 Tomcat 。安装 Java 、环境变量 path 的设置以及 cmd 小
- jstat命令简介jstat(Java Virtual Machine Statistics Monitoring Tool)是JDK提供的
- 在Controller层时,往往会需要校验或验证某些操作,而在每个Controller写重复代码,工作量比较大,这里在Springboot项