主线程等待所有线程结束之后再执行

如何让主线程等待所有线程结束之后再执行

1、Future的机制,使用Future.get()阻塞等待结果(Future,FutureTask)

2、CountDownLatch同步工具类,此类的作用就是一个线程等待所有线程结束之后再执行

3、CompletableFuture  与Future机制类似,同样是使用get阻塞等待结果,不过此类可以使任务并行合并以及串行,相当于是Future的增强版

4、线程池的isTerminated方法,当调用shutdown()方法后,并且所有提交的任务完成后才会返回为true

5、Thread的join方法,等待主线程结束

Future机制 

FutureTask

package com.alibaba.fescar.core.protocol.test;import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class TestFuture {public static void main(String[] args) {FutureTask<Integer> futureTask = new FutureTask<Integer>(()-> {System.out.println("当前线程执行");return 1;});new Thread(futureTask).start();try {// 阻塞获取值Integer integer = futureTask.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}System.out.println("主线程执行");}}

执行结果 

Future

package com.alibaba.fescar.core.protocol.test;import java.util.concurrent.*;public class TestFuture {public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(1);Future<Integer> task = pool.submit(() -> {System.out.println("当前线程执行");return 1;});try {// 阻塞获取结果Integer integer= task.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}System.out.println("主线程执行");}}

执行结果 

结果分析:这里借用线程池提交任务,程序没有退出,是因为线程池没有shutdown,熟悉下线程池的submit方法

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);         
Future<?> submit(Runnable task);

如上所示,线程池接受Callable 和Runnable任务,返回Future接口的上转型对象,和FutureTask同理,

有关于Runnable、Future、Callable、FutureTask 请参考文章:

Runnable、Future、Callable、FutureTask

CountDownLatch 

package com.alibaba.fescar.core.protocol.test;import java.util.concurrent.CountDownLatch;public class TestCountDown {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(1);new Thread(() -> {System.out.println("当前线程结束");latch.countDown();}).start();latch.await();System.out.println("主线程结束");}}

 执行结果

 latch.dountDown()调用,计数器会减一,latch.await()会阻塞主线程直到0放行

CompletableFuture 

package com.alibaba.fescar.core.protocol.test;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;public class TestCompletableFuture {public static void main(String[] args) throws ExecutionException, InterruptedException {/*** supplyAsync与runAsync的区别在于:supplyAsync有返回值,而runAsync没有返回值*/CompletableFuture<Integer> current1 = CompletableFuture.supplyAsync(() -> {System.out.println("当前线程1执行");return 3;});/*** 合并两个任务,两个任务可以同时执行,都执行成功后,执行最后的BiFunction操作。*/CompletableFuture<Integer> current2 = CompletableFuture.supplyAsync(() -> {System.out.println("当前线程2执行");return 2;}).thenCombine(current1,(res1,res2)->res1 * res2);System.out.println(current2.get());System.out.println("主线程执行");}
}

执行结果 

 CompletableFuture实现了Future接口,当其get的时候同样阻塞主线程执行, CompletableFuture在于可以多任务串行,以及并行执行,操作空间更广

具体用法请参考文章:CompletableFuture用法

线程池的isTerminated方法

package com.alibaba.fescar.core.protocol.test;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TestThreadPool{public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(3);pool.execute(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}});pool.execute(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}});pool.shutdown();while (true) {if (pool.isTerminated()) {System.out.println("线程池中的任务执行结束");break;}}System.out.println("主线程结束");}}

执行结果 

 

isTerminated,当调用shutdown()方法后,并且所有提交的任务完成后才会返回为true 

Thread的join方法

package com.alibaba.fescar.core.protocol.test;public class TestThreadJoin {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {System.out.println("t1执行");Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}});t1.start();Thread t2 = new Thread(() -> {try {System.out.println("t2执行");Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}});t2.start();t1.join();t2.join();System.out.println("主线程结束");}
}

执行结果

 Thread中的join方法,用于等待本线程结束,同时阻塞其他线程,也叫插队线程,yeild线程礼让,让出执行权,wait 线程等待,释放锁, sleep线程休眠 不会释放锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/19560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

音视频开发—FFmpeg播放YUV文件,YUV转换为JPEG操作

文章目录 1.使用命令行播放YUV数据1.1命令解析1.2参数说明 2.使用C语言实现将YUV数据转为JPEG图片格式2.1需求分析2.2读取YUV源文件2.3将YUV数据封装为AVFrame2.4将NV12 转换为YUV420平面格式2.5初始化MJPEG编码器2.6将YUV420P编码为JPEG2.7将编码数据写入图片文件2.8完整代码 …

App自动化测试_Python+Appium使用手册

一、Appium的介绍 Appium是一款开源的自动化测试工具&#xff0c;支持模拟器和真机上的原生应用、混合应用、Web应用&#xff1b;基于Selenium二次开发&#xff0c;Appium支持Selenium WebDriver支持的所有语言&#xff08;java、 Object-C 、 JavaScript 、p hp、 Python等&am…

安装flask:后端框架的学习之旅

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、创建虚拟环境 1. 引入虚拟环境的概念 2. 创建Flask虚拟环境 三、安装Flask…

CSRF跨站请求伪造漏洞

CSRF跨站请求伪造漏洞 1.CSRF漏洞概述2.防御CSRF攻击3.CSRF防御绕过CSRF令牌未绑定到用户会话自定义标头令牌绕过绕过Referer检查关键词绕过 4.利用示例使用HTML标签进行GET表单 GET 请求表单POST请求通过 iframe 发送表单 POST 请求Ajax POST 请求 5.CSRF BP 验证方法6.CSRF测…

HTTP协议介绍与TCP协议的区别

1、HTTP介绍 HTTP&#xff08;超文本传输协议&#xff0c;Hypertext Transfer Protocol&#xff09;是一种用于从网络传输超文本到本地浏览器的传输协议。它定义了客户端与服务器之间请求和响应的格式。HTTP 是基于TCP/IP 进行数据的通信&#xff0c;通常使用端口 80/8080。HTT…

软件需求规格说明书(Word原件@配套软件全资料)

软件需求规格说明书编写规范编写规范 1.项目背景 2.项目目标 3.系统架构 4.总体流程 5.名称解释 6.功能模块 软件项目相关全套精华资料包获取方式①&#xff1a;点我获取 获取方式②&#xff1a;本文末个人名片直接获取。 软件资料清单列表部分文档清单&#xff1a;工作安排任…

Optional类

一、概述 泛型类、java8引进的、java.util包里 二、作用 解决空指针异常带来的不便 三、做法 将对象封装为一个Optional对象&#xff0c;如果封装的对象为空&#xff08;即该对象不存在&#xff09;&#xff0c;可以使用默认值和或者执行默认操作 四、方法 1、empty() 创…

【Qt知识】Qt Creator快捷键

以下是Qt Creator中的一些常用快捷键列表&#xff08;持续更新&#xff09;&#xff1a; 基本编辑 多行注释/取消多行注释: Ctrl /编译工程: Ctrl B运行工程: Ctrl R整行上移/下移: Ctrl Shift ↑/↓查找: Ctrl F函数声明和定义切换: F2向下查找: F3头文件和源文件切换:…

【postgresql初级使用】初识触发器,在数据行发生变化时自动执行用户行为,也可以SQL级别触发,特别是视图上可以有触发器了

初识触发器 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章目录 初识触发器概…

【成品设计】基于RT-thread星火开发板的智能监测系统设计

《基于RT-thread星火开发板的智能监测系统设计》 所需器件&#xff1a; 主控&#xff1a;STM32F407星火开发板。温湿度传感器&#xff1a;采集当前环境中的温湿度。环境传感器&#xff1a;采集当前环境中的光照强度。CO2传感器&#xff0c;采集当前环境中的C02浓度。粉尘传感…

excel怎么对非数字求和汇总?

如&#xff1a;学生小王的成绩为&#xff1a;A&#xff0c;A&#xff0c;A&#xff0c;A&#xff0c;B&#xff0c;B-……想得到的成绩汇总求和为&#xff1a;2A,2A,1B,1B- 如果在低版本里&#xff0c;用公式计算可能相当复杂&#xff0c;但是有了TEXTJOIN函数和UNIQUE函数&…

校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)

校园交友网站 目录 基于SprinBootvue的校园交友网站 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台功能模块 5.2.1管理员功能模块 5.2.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#x…

CSS学习笔记:bootstrap的介绍、下载、使用及响应式布局的实现

介绍 Bootstrap 是由 Twitter 公司开发维护的前端 UI 框架&#xff0c;它提供了大量编写好的CSS 样式 bootstrap过时了吗&#xff1f; 其实在学bootstrap这一部分的网课时&#xff0c;在弹幕上看到一些同学说bootstrap已经过时了&#xff0c;这里谈谈我的看法 我的前端学习…

3天13部,端午档电影数何以是五一档2倍?

离端午还有12天&#xff0c;院线端午档再上热搜。 截止至5月29日&#xff0c;本次端午档将有13部电影在3天的节假日内集中上映&#xff0c;这一数量仅比2021年端午档的最高纪录少了2部&#xff0c;几乎是今年五一档期上映影片数量&#xff08;7部&#xff09;的两倍。 并且与…

UE5 Http Server

前言 最近要用UE 作为一个服务器去接收来自外部的请求&#xff0c;从而在UE中处理一些内容&#xff0c;但是之前只做过请求&#xff0c;哪整过这玩意&#xff0c;短期内还得出结果&#xff0c;那怎么搞嘞&#xff0c;本着省事的原则就找找呗&#xff0c;有没有现成的&#xff0…

结构体中内存的对齐

前言 学C的同学应该知道~ 想精通C语言就不得不面对—指针与内存 续上次指针进阶&#xff0c;这一章我来聊一聊C语言内存对齐的问题 学习结构体的你有没有注意过结构体向系统申请的内存为多少呢的&#x1f601; 思考 #include<stdio.h> typedef struct s1 {char a;char …

Qt6同时使用Qt3DCore与QtGUI时QTransform类冲突问题

在Qt GUI模块有一个QTransform类&#xff0c;在Qt3D Core模块也有一个QTransform类&#xff0c;如果不特殊指定一下会报错

全新/二手KEITHLEY 2400 数字万用表

吉时利Keithley 2400数字源表&#xff0c;200V&#xff0c;1A&#xff0c;20W Keithley 2400 源表是一款 20W 仪器&#xff0c;可输出和测量 5V&#xff08;输出&#xff09;和 1V&#xff08;测量&#xff09;至 200V DC 的电压以及 10pA 至 1A 的电流。该万用表功能包括高重复…

【linux深入剖析】进程间通信

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1.进程间通信目的2. 什么…

react 怎样向ant table添加按钮,以及文本溢出隐藏?

这些都是一些组件自带的方法&#xff0c;只不过是不知道该怎么用&#xff0c;上面的内容可以直接拿去用&#xff0c;&#xff08;事件除外&#xff0c;要自己绑&#xff0c;还有引入的组件&#xff09;&#xff01;