Java使用CountDownLatch实现网络同步请求的示例代码
作者:抓手 发布时间:2022-04-23 18:40:52
CountDownLatch 是一个同步工具类,用来协调多个线程之间的同步,它能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。
这里是使用CountDownLatch和多线程完成商品信息异步组装:
import java.time.LocalDateTime;
import java.util.StringJoiner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author 向振华
* @date 2023/01/04 14:01
*/
public class Test {
public static void main(String[] args) {
// 创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
CountDownLatch countDownLatch = new CountDownLatch(3);
System.out.println("开始 " + LocalDateTime.now());
StringJoiner sj = new StringJoiner("、");
// 线程1
executorService.execute(() -> {
try {
String do1 = do1();
sj.add(do1);
} catch (Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
// 线程2
executorService.execute(() -> {
try {
String do2 = do2();
sj.add(do2);
} catch (Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
// 线程3
executorService.execute(() -> {
try {
String do3 = do3();
sj.add(do3);
} catch (Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(sj.toString());
System.out.println("完成 " + LocalDateTime.now());
}
private static String do1() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1查询商品规格信息");
return "商品规格";
}
private static String do2() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("2查询商品价格信息");
return "商品价格";
}
private static String do3() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3查询商品图片信息");
return "商品图片";
}
}
输出结果:
开始 2023-01-04T14:16:40.441
1查询商品规格信息
3查询商品图片信息
2查询商品价格信息
商品规格、商品图片、商品价格
完成 2023-01-04T14:16:45.468
知识补充
1.背景
countDownLatch是在java1.5被引入,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。
存在于java.util.cucurrent包下
2.概念
countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
3.源码
countDownLatch类中只提供了一个构造器:
//参数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() { };
4.示例
普通示例
public class CountDownLatchTest {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
System.out.println("主线程开始执行…… ……");
//第一个子线程执行
ExecutorService es1 = Executors.newSingleThreadExecutor();
es1.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
System.out.println("子线程:"+Thread.currentThread().getName()+"执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
});
es1.shutdown();
//第二个子线程执行
ExecutorService es2 = Executors.newSingleThreadExecutor();
es2.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程:"+Thread.currentThread().getName()+"执行");
latch.countDown();
}
});
es2.shutdown();
System.out.println("等待两个线程执行完毕…… ……");
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("两个子线程都执行完毕,继续执行主线程");
}
}
结果集:
主线程开始执行…… ……
等待两个线程执行完毕…… ……
子线程:pool-1-thread-1执行
子线程:pool-2-thread-1执行
两个子线程都执行完毕,继续执行主线程
来源:https://blog.csdn.net/Anenan/article/details/128547521


猜你喜欢
- java文字识别程序的关键是寻找一个可以调用的OCR引擎。tesseract-ocr就是一个这样的OCR引擎,在1985年到1995年由HP
- 1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),
- 废话目前流行的前后端分离让Java程序员可以更加专注的做好后台业务逻辑的功能实现,提供如返回Json格式的数据接口就可以。SpringBoo
- 1.垃圾收集算法的核心思想Java语言建立了垃圾收集机制,用以跟踪正在使用的对象和发现并回收不再使用(引用)的对象。该机制可以有效防范动态内
- 布隆过滤器原理很简单:就是把一个字符串哈希成一个整数key,然后选取一个很长的比特序列,开始都是0,在key把此位置的0变为1;下次进来一个
- spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问
- 一、MVVM 和 MVVMLight介绍MVVM是Model-View-ViewModel的简写。类似于目前比较流行的MVC、MVP设计模式
- 本文实例为大家分享了Android绘制钟表的具体代码,供大家参考,具体内容如下首先要画一个表,我们要先知道步骤如何:1、仪表盘----外面最
- 1、xml代码:<?xml version="1.0" encoding="utf-8"?&g
- 被覆盖比较好理解,类似于多态的实现,访问时通过类方法表来访问,你实际是什么类型,访问的方法就是那个类型的方法而不会是你的父类的方法。被隐藏是
- package com.smart.frame.task.autoTask;import java.util.Collection;impo
- 本文章主要讲二维数组定义,用法。1.什么是二维数组在二维数组多个元素为一维数组的数组就称为二维数组2.定义格式格式一:元素的数据类型[][]
- 我们开启一个线程,线程每隔一秒发送一次消息,我们在消息中更新TextView上显示的时间就ok了。首先我们在布局文件中放一个TextView
- 序本文主要研究下在带有lombok(1.16.20版本)注解的代码在java10下的编译问题。问题Fatal error compiling
- 线程概念进程:启动一个应用程序就叫一个进程。 接着又启动一个应用程序,这叫两个进程。每个进程都有一个独立的内存空间;进程也是程序的一次执行过
- 本文实例为大家分享了Android实现Window弹窗效果的具体代码,供大家参考,具体内容如下效果图第一步 准备弹窗的布局,新建XML文件
- 前面有文章曾经地介绍过MediaPlayer的基本用法,这里就更加深入地讲解MediaPlayer的在线播放功能。本文主要实现MediaPl
- 这篇文章主要介绍了通过实例了解spring使用构造器注入的原因,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 简介SpringBoot提供了HATEOAS的便捷使用方式,本文详细讲解SpringBoot提供的这些基本方法。链接LinksHATEOAS
- 对某个类型中的方法进行拦截,然后加入固定的业务逻辑,这是AOP面向切面编程可以做的事,在springboot里实现aop的方法也有很多, s