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,CountDownLatch,网络,同步,请求
0
投稿
猜你喜欢
java 中Map详解及实例代码
2023-06-06 01:27:37
C#实现窗口之间的传值
2022-05-26 08:28:14
C#微信公众号开发之接收事件推送与消息排重的方法
2022-01-31 08:44:46
Android编程之文件读写操作与技巧总结【经典收藏】
2023-10-16 02:20:52
java interface的两个经典用法
2021-08-17 06:20:56
使用@Validated 和 BindingResult 遇到的坑及解决
2022-12-18 20:36:28
Android中的SQL查询语句LIKE绑定参数问题解决办法(sqlite数据库)
2023-09-12 14:04:06
Java如何利用状态模式(state pattern)替代if else
2021-08-15 09:31:08
MyBatis一对多嵌套查询的完整实例
2023-07-12 02:49:56
winform导出dataviewgrid数据为excel的方法
2023-09-25 15:01:38
Android服务Service教程
2022-02-19 13:05:40
关于springboot中对sqlSessionFactoryBean的自定义
2022-12-09 06:05:09
C#实现插入排序
2023-07-02 13:16:58
Springboot Session共享实现原理及代码实例
2022-12-16 03:29:52
Java Swing实现让窗体居中显示的方法示例
2023-11-06 02:59:07
Android Universal ImageLoader 缓存图片
2023-03-04 05:16:54
Gradle的基本使用
2023-05-29 00:08:42
spring data JPA 中的多属性排序方式
2023-01-14 19:26:41
Android平台预置GMS包后关机闹钟失效问题及解决方法
2022-12-31 05:52:33
idea打包java程序(包含依赖的所有jar包)
2023-02-13 00:10:26