1、通过join()的方式

子线程调用join()的时候,主线程等待子线程执行完再执行。如果让多个线程顺序执行的话,那么需要他们按顺序调用start()。

   /*** - 第一个迭代(i=0):*     启动线程t1 -> 然后调用t1.join()。*     主线程(执行testMethod2的线程)会在t1.join()处阻塞,直到t1线程执行完毕。* - 第二个迭代(i=1):*     只有等到t1执行完毕,主线程才会继续执行,然后启动线程t2,并调用t2.join(),主线程等待t2执行完毕。* - 第三个迭代(i=2):*     同样,主线程等待t2执行完毕后,启动t3,然后等待t3执行完毕。* @throws InterruptedException*/@Testvoid testMethod1() throws InterruptedException {List<Thread> list = new ArrayList<>();for (int i = 1; i <= 3; i++) {Thread thread = new Thread(() -> {log.info("{} 执行~", Thread.currentThread().getName());},"t" + i);list.add(thread);}for (int i = 0; i < list.size(); i++) {list.get(i).start();//他阻塞的是主线程,当前线程执行完后,主线程才会执行list.get(i).join();}}

2、通过CountDownLatch 的方式

countDown():没调用一次,计数器就会减 1。当计数器减到 0 时,调用await()的线程才会被唤醒。
await():当计数器不为 0 的时候,调用await()的线程会被阻塞。

   /***  1、让第一个线程执行,完事调用countDown()再对countDownLatch记数减 1*  2、第二个线程调用await()去唤醒,但是需要线程一执行完,*     因为只有记数为 0 的话,当前线程才会被唤醒,依次类推*/@Testvoid testMethod2(){CountDownLatch countDownLatch = new CountDownLatch(1);for (int i = 1; i <= 3; i++) {final int threadId = i;new Thread(() -> {if (threadId != 1) {try {//等待计数器归零,再继续往下执行,否则在此处阻塞countDownLatch.await();} catch (InterruptedException e) {throw new RuntimeException(e);}}log.info("{} 执行~", Thread.currentThread().getName());//计数器减 1countDownLatch.countDown();},"t" + i).start();}}

3、通过Semaphore的方式

通过信号量控制,每个线程在开始执行前需要获取一个许可,执行完毕后释放下一个线程需要的许可。

    /*** 只让第一个信号量有一个许可,另外两个信号量没有许可* 1、第一个线程获取到许可,执行打印,然后释放下一个信号量的许可* 2、第二个线程获取到许可,执行打印,然后释放下一个信号量的许可* 3、第三个线程获取到许可,执行打印*/@Testvoid testMethod3(){int length = 3;List<Semaphore> semaphoreList = new ArrayList<>();for (int i = 1; i <= length; i++) {Semaphore semaphore = new Semaphore(i == 1 ? 1 : 0);semaphoreList.add(semaphore);}for (int j = 0; j < length; j++) {final int theadIndex = j;new Thread(() -> {try {//获取许可semaphoreList.get(theadIndex).acquire();log.info("{} 执行~", Thread.currentThread().getName());} catch (InterruptedException e) {throw new RuntimeException(e);}finally {//释放许可if (theadIndex != length - 1) {semaphoreList.get(theadIndex + 1).release();}}},"t" + (j + 1)).start();}}

4、CompletableFuture的方式

原理:异步任务链式调用
优势:代码简洁,内置线程池管理

CompletableFuture.runAsync(() -> System.out.println("t1")).thenRun(() -> System.out.println("t2")).thenRun(() -> System.out.println("t3")).join();  // 阻塞等待全部完成

5、利用线程池

原理:所有任务提交到单线程队列顺序执行
优势:自动管理线程生命周期
注意:实际是同一个线程执行所有任务

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("t1"));
executor.submit(() -> System.out.println("t2"));
executor.submit(() -> System.out.println("t3"));
executor.shutdown();

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

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

相关文章

在 Vue 项目中关闭 ESLint 规则

在 Vue 2 项目中关闭 ESLint 规则有以下几种方法&#xff0c;根据您的需求选择合适的方式&#xff1a; 1. 完全禁用 ESLint 修改 vue.config.js&#xff08;推荐&#xff09; module.exports {// 关闭 ESLintlintOnSave: false }或修改 package.json {"scripts": {&…

电脑息屏工具,一键黑屏超方便

软件介绍 今天为大家推荐一款实用的PC端屏幕管理工具——CloseDsp。这款"息屏小能手"能一键关闭显示器&#xff0c;解决各种场景下的屏幕管理需求。 核心功能 CloseDsp最突出的特点是能瞬间关闭显示器屏幕。只需点击"关闭显示器"按钮&#xff0c;屏幕…

嵌入式调试LOG日志输出(以STM32为例)

引言在嵌入式系统开发中&#xff0c;调试是贯穿整个生命周期的关键环节。与传统PC端程序不同&#xff0c;嵌入式设备资源受限&#xff08;如内存、存储、处理器性能&#xff09;&#xff0c;且运行环境复杂&#xff08;无显示器、键盘&#xff09;&#xff0c;传统的断点调试或…

Zephyr的设备驱动模型

默认配置默认配置 boards/arm/nucleo_f401re/ ├── nucleo_f401re.dts ← 板卡设备树主入口 ├── nucleo_f401re_defconfig ← 默认 Kconfig 配置 ├── board.cmake ← CMake 构建入口overlay1.新增加驱动需要修改对应板的设备树文件&#xf…

Mysql字段没有索引,通过where x = 3 for update是使用什么级别的锁

没有索引时&#xff0c;FOR UPDATE 会锁住整个表 现在&#xff0c;你正在一本一本地翻看所有书&#xff0c;寻找“维修中”的书&#xff0c;并且你对管理员说&#xff1a;“在我清点和修改完之前&#xff0c;别人不能动这些书&#xff0c;也不能往这个范围里加新书&#xff01;…

TCP-与-UDP-协议详解:原理、区别与应用场景全解析

TCP 与 UDP 协议详解&#xff1a;原理、区别与应用场景全解析 在日常使用网络的过程中&#xff0c;我们经常听到 TCP 和 UDP 这两个词。你打开网页、发送消息、观看视频&#xff0c;背后都在使用 TCP 或 UDP 进行数据传输。那么这两个协议到底是怎么工作的&#xff1f;它们之间…

GitHub信息收集

目录 简介 一、入门搜索技巧 1. 基本关键词搜索 2. 文件类型限定搜索 3. 用户/组织定向搜索 二、精准定位技巧 1. 组合搜索条件 2. 排除干扰结果 3. 路径限定搜索 三、防御建议 四、法律与道德提醒 简介 GitHub作为全球最大的代码托管平台&#xff0c;存储着数十亿…

由 DB_FILES 参数导致的 dg 服务器无法同步问题

由 DB_FILES 参数导致的 dg 服务器无法同步问题 用户反映&#xff0c;dg 服务器数据从昨晚&#xff08;7月8日&#xff09;开始停止同步。 连接服务器发现没有 mrp 进程&#xff0c;并且 OPEN_MODE 参数也不正确。具体情况如下所示&#xff1a; SQL> select process, status…

Go语言泛型-泛型对代码结构的优化

在Go语言中,Go泛型-泛型对代码结构的优化部分主要探讨了泛型如何帮助我们优化代码结构、减少重复代码,并提高代码的可维护性、可读性和复用性。以下是详细内容: 一、引言 Go 1.18 引入了泛型,极大地提高了语言的灵活性。泛型使得我们可以编写更加通用、可复用且类型安全的…

【1-快速上手】

文章目录前言简介什么是 Konva&#xff1f;安装 Konva概述它是如何工作的&#xff1f;基本形状样式事件拖放滤镜动画选择器序列化与反序列化性能前言 结合项目实际业务需求&#xff0c;在 Fabric、Konva 等图形化框架中&#xff0c;我选择了性能表现好的 Konva。首先去学习官方…

【LeetCode】209. 长度最小的子数组(前缀和 + 二分)

【LeetCode】209. 长度最小的子数组&#xff08;前缀和 二分&#xff09;题目描述前缀和二分优化前缀和总结二分总结题目描述 题目链接&#xff1a;【LeetCode】209. 长度最小的子数组&#xff08;前缀和 二分&#xff09; 给定一个含有 n 个整数的数组和一个整数 target。…

文件系统----底层架构

当我们谈到文件系统的时候&#xff0c;最重要的点在于&#xff1a;文件的内容与属性是如何存储在磁盘中的&#xff1f;以及操作系统是如何精准定位到这些文件内容的&#xff1f;在谈及文件的内核前&#xff0c;我们先来了解一下储存文件的硬件-----硬盘一.理解硬件首先我们来看…

小程序开发平台,自主开发小程序源码系统,多端适配,带完整的部署教程

温馨提示&#xff1a;文末有资源获取方式全开源与自主开发源码完全开放&#xff1a;开发者可自由修改前端界面、后端逻辑及数据库结构&#xff0c;支持深度定制&#xff08;如调整用户端交互流程、商家端管理功能等&#xff09;。技术栈透明&#xff1a;基于主流技术&#xff0…

stp拓扑变化分类

Max Age 20sHellotime 2sForward delay 153、拓扑改变需要多长时间1&#xff09;根桥故障&#xff1a;需要50秒&#xff08;Max age2个forwarding delay&#xff09;2&#xff09;非直连链路&#xff1a;非直连故障在稳定的STP网络&#xff0c;非根桥会定期收到来自根桥的BPDU报…

一、深度学习——神经网络

一、神经网络 1.神经网络定义&#xff1a;人工神经网络&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09;也简称为神经网络&#xff08;NN&#xff09;&#xff0c;是一种模仿生物神经网络结构和功能的计算模型。人脑可以看作是一个生物神经网络&#xff0c;由…

【牛客算法】 小红的奇偶抽取

文章目录 一、题目介绍1.1 题目描述1.2 输入描述1.3 输出描述1.4 示例二、解题思路2.1 核心算法设计2.2 性能优化关键2.3 算法流程图三、解法实现3.1 解法一:字符串分离法3.1.1 初级版本分析3.2 解法二:数学逐位构建法(推荐)3.2.1 优化版本分析四、总结与拓展4.1 关键优化技…

Maven 继承:构建高效项目结构的利器

一、引言 Maven 是一个强大的项目管理工具&#xff0c;它通过标准化的项目结构和依赖管理极大地简化了 Java 项目的开发流程。在 Maven 中&#xff0c;继承是一种非常有用的功能&#xff0c;它允许我们创建一个父项目&#xff0c;其他子项目可以继承这个父项目的配置信息&#…

Mysql组合索引的update在多种情况下的间隙锁的范围(简单来说)

简单来说&#xff0c;当 UPDATE 语句的 WHERE 条件使用了组合索引&#xff0c;并且需要锁定不存在的“间隙”来防止幻读时&#xff0c;就会产生间隙锁。间隙锁的范围取决于 WHERE 条件如何利用组合索引&#xff0c;以及数据库的隔离级别。 我们用图书馆的例子。比如&#xff1a…

什么是Apache Ignite的affinity(亲和性)

在 Apache Ignite 中&#xff0c; affinity&#xff08;亲和性&#xff09; 是一种用于控制数据分布和查询性能的重要机制。它允许开发者指定数据如何在集群中的节点之间分布&#xff0c;从而优化数据访问和查询效率。以下是关于 affinity 的详细解释&#xff1a;数据亲和性&a…

youtube图论

dfs排序lifo & fifo存储方式邻接矩阵dijstra处理过的保存/更新&#xff0c;意味着一个节点避免了重复访问bfs dfs