原文链接:线程题大全

Java 并发库同步辅助类

CountDownLatch

工作机制:初始化一个计数器,此计数器的值表示需要等待的事件数量。

提供了两个主要方法:

  • await():当一个线程调用此方法时,它将阻塞,直到计数器的值为 0
  • countDown():用于减少计数器的值。通常表示一个事件已经发生了(如任务完成),当计数器的值减到 0 时,所有调用 await()并阻塞的线程将被唤醒并继续执行

重要特性:

  • 不可重置:一旦计数器的值为 0,就不能再被重置回初识值或其他任何值
  • 一次性的:计数值到达 0 后,所有在 await()方法上等待的线程将被释放,而后续的 await()方法调用将立即通过,不会进行阻塞
  • 多用途同步工具:能被用于多种目的,等待服务的初始化、一组任务或某个事件的发生

示例:在两个工作线程结束后再调用主线程

CountDownLatch latch = new CountDownLatch(2); // 设定计数器初始值为2// 创建第一个线程,完成某项任务后调用countDown方法
new Thread(() -> {System.out.println("线程1执行...");latch.countDown();System.out.println("线程1完成操作,计数器减一");
}).start();// 创建第二个线程,也是完成某项任务后调用countDown方法
new Thread(() -> {System.out.println("线程2执行...");latch.countDown();System.out.println("线程2完成操作,计数器减一");
}).start();try {// 调用await方法的线程会被阻塞,直到计数器的值变为0latch.await();System.out.println("两个线程的操作均已完成,主线程继续执行");
} catch (InterruptedException e) {e.printStackTrace();
}
CyclicBarrier

工作机制:允许一组线程相互等待到达一个共同屏障点

重要特性:

  • 屏障:允许提供一个 Runnable 任务,在所有线程都到达屏障,线程释放前执行该任务。通常用于合并最终结果或者进行某种必须等到所有线程都到达屏障点后才能执行的操作
  • 等待线程数:在创建 CyclicBarrier 时,需要指定等待的线程数量。当指定数量的线程都调用 await()方法,表示它们都到达了屏障点,随后这些线程都将被释放
  • 超时与中断:线程在调用 await()方法时可以选择设置超时时间,超时或者被中断都将导致线程提前释放,并抛出相应异常
  • 重置:释放等待线程后重置计数器。

示例:当四个线程都达到屏障后,打印一句话,然后每个线程继续执行它们的任务

public class CyclicBarrierExample {// 创建一个新的CyclicBarrier,当四个参与者到达时执行屏障操作private CyclicBarrier barrier = new CyclicBarrier(4, () -> System.out.println("所有线程到达屏障点,屏障操作执行!"));public void startTask(String name) {new Thread(() -> {System.out.println(name + "开始执行任务...");// 模拟任务耗时try {Thread.sleep((int)(Math.random() * 1000));} catch (InterruptedException e) {e.printStackTrace();}System.out.println(name + "到达屏障点,等待其他线程...");try {// 调用await方法等待其他线程都到达屏障点barrier.await();} catch (Exception e) {e.printStackTrace();}System.out.println(name + "继续执行后续操作");}).start();}public static void main(String[] args) {CyclicBarrierExample example = new CyclicBarrierExample();example.startTask("线程A");example.startTask("线程B");example.startTask("线程C");example.startTask("线程D"); // 当所有四个线程达到屏障点,将一起释放,然后执行屏障操作}
}

线程交叉打印模版

public class CrossPrinter {private int state;private final int printCount;public CrossPrinter(int printCount) {// state用来确定下次打印this.state = 0;// 打印次数this.printCount = printCount;}public void printLetter(String Letter, int crossState ,int curState) {for (int i = 0; i < printCount; i++) {synchronized (this) {while (state % crossState != curState) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() + ":" + Letter);state++;notifyAll();}}}public static void main(String[] args) {CrossPrinter crossPrinter = new CrossPrinter(5);// Thread A打印"A"new Thread(() -> crossPrinter.printLetter("A", 2,0), "Thread A").start();// Thread B打印"B"new Thread(() -> crossPrinter.printLetter("B", 2,1), "Thread B").start();}}

上述完成了两线程交叉打印"A"、“B”,具体说明下

  • printCount:控制交叉打印次数
  • state:全局变量,指明线程已经执行多少次了
  • crossState:指明有多少个线程进行交叉
  • curState:指明当前线程
  • Letter:当前线程打印内容

可用于:

  • 多线程交叉打印 A、B、C…
  • 两线程交叉打印奇偶数
三线程交叉打印 A、B、C

模版中是两线程交叉打印 A、B,只需要做简单替换就能实现三线程交叉打印 A、B、C

crossState:3

新增线程 C 如下

// Thread A打印"A"
new Thread(() -> crossPrinter.printLetter("A", 3,0), "Thread A").start();// Thread B打印"B"
new Thread(() -> crossPrinter.printLetter("B", 3,1), "Thread B").start();// Thread C打印"C"
new Thread(() -> crossPrinter.printLetter("C", 3,2), "Thread C").start();
两线程交叉打印奇偶数

比如要求打印到两线程交叉打印到 10

state 控制线程进行轮次,此时可以换为 while 条件,用来控制跳出循环

crossState:2,表示两线程

完整代码如下:

public class CrossPrinter {private int state;private final int printCount;public CrossPrinter(int printCount) {// state用来确定下次打印this.state = 0;// printCount表示打印次数this.printCount = printCount;}public void printNumber(int crossState ,int curState) {while (state < printCount) {synchronized (this) {while (state % crossState != curState) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() + ":" + state);state++;notifyAll();}}}public static void main(String[] args) {CrossPrinter crossPrinter = new CrossPrinter(10);// Thread A打印偶数new Thread(() -> crossPrinter.printNumber(2,0), "Thread A").start();// Thread B打印奇数new Thread(() -> crossPrinter.printNumber(2,1), "Thread B").start();}}
三线程交叉打印斐波那契数列

新增 oneNum、twoNum 来记录前两个数

完整代码如下

public class CrossPrinter {private int state;private int oneNum;private int twoNum;private final int printCount;public CrossPrinterThree(int printCount) {this.state = 3;this.oneNum = 1;this.twoNum = 1;this.printCount = printCount;}public static void main(String[] args) {CrossPrinterThree crossPrinterThree = new CrossPrinter(10);// 三线程交叉打印斐波那契数列new Thread(() -> crossPrinterThree.printNum(3, 0), "Thread-A").start();new Thread(() -> crossPrinterThree.printNum(3, 1), "Thread-B").start();new Thread(() -> crossPrinterThree.printNum(3, 2), "Thread-C").start();}private void printNum(int crossState, int curState) {while (state < printCount) {synchronized (this) {while (state % crossState != curState) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}int curNum = oneNum + twoNum;System._out_.println(Thread._currentThread_().getName() + ":" + curNum);// 更新前两个数oneNum = twoNum;twoNum = curNum;state++;notifyAll();}}}}

多线程任务执行 A -> B, A -> C

实现方案:CountDownLatch

  • 为线程 B、C 分别设置 CountDownLatch 锁,当线程 A 执行后,唤醒线程 B、C 的 CountDownLatch 锁
public class MultiThreadTaskExecution {// 使用两个初始计数为1的CountDownLatch来实现一对多的通知机制private CountDownLatch latchToB = new CountDownLatch(1);private CountDownLatch latchToC = new CountDownLatch(1);public void taskA() {System.out.println("任务A执行中...");try {Thread.sleep(100); // 模拟任务A执行时间} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务A执行完毕,通知任务B、C开始执行...");latchToB.countDown();latchToC.countDown();}public void taskB() {try {latchToB.await();System.out.println("任务B执行中...");Thread.sleep(100); // 模拟任务B执行时间System.out.println("任务B执行完毕...");} catch (InterruptedException e) {e.printStackTrace();}}public void taskC() {try {latchToC.await();System.out.println("任务C执行中...");Thread.sleep(100); // 模拟任务C执行时间System.out.println("任务C执行完毕...");} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {MultiThreadTaskExecution taskExecution = new MultiThreadTaskExecution();new Thread(taskExecution::taskB).start();new Thread(taskExecution::taskC).start();new Thread(taskExecution::taskA).start();}}

线程 A、B、C 都到达屏障点才执行后续操作

实现方案:CyclicBarrier

  • 设置屏障数量 3,同时可设置一个 Runnable 任务,当都达到时输出一句话。
public class CyclicBarrierOne {// 创建一个新的CyclicBarrier,当3个参与者到达时执行屏障操作private CyclicBarrier barrier = new CyclicBarrier(3, () -> System._out_.println("所有线程到达屏障点,屏障操作执行!"));public static void main(String[] args) {CyclicBarrierOne cyclicBarrierOne = new CyclicBarrierOne();new Thread(() -> cyclicBarrierOne.startTask(), "Thread-A").start();new Thread(() -> cyclicBarrierOne.startTask(), "Thread-B").start();new Thread(() -> cyclicBarrierOne.startTask(), "Thread-C").start();}private void startTask() {System._out_.println(Thread._currentThread_().getName() + "开始执行任务...");try {Thread._sleep_(100);} catch (InterruptedException e) {e.printStackTrace();}System._out_.println(Thread._currentThread_().getName() + "到达屏障点,等待其他线程...");try {barrier.await();} catch (Exception e) {e.printStackTrace();}System._out_.println(Thread._currentThread_().getName() + "继续执行后续操作");}}

10 个线程同时启动

public class SimultaneousStart {private static final int _N _= 10;_// 创建一个CountDownLatch用于线程启动的信号_
_    _private static final CountDownLatch _startSignal _= new CountDownLatch(1);_// 创建一个 CountDownLatch 用于等待所有线程完成的信号_
_    _private static final CountDownLatch _doneSignal _= new CountDownLatch(_N_);public static void main(String[] args) throws InterruptedException {Runnable task = () -> {try {_startSignal_.await(); _// 等待启动信号_
_                _System._out_.println(Thread._currentThread_().getName() + " has started");Thread._sleep_(2000); _// 模拟任务执行_
_                _System._out_.println(Thread._currentThread_().getName() + " has finished");} catch (InterruptedException e) {Thread._currentThread_().interrupt();} finally {_doneSignal_.countDown(); _// 完成信号_
_            _}};_// 创建并启动N个线程_
_        _for (int i = 0; i < _N_; i++) {new Thread(task, "Thread-" + (i + 1)).start();}_// 主线程等待片刻,确保所有线程已经启动并在等待_
_        _Thread._sleep_(1000);System._out_.println("All threads are ready, starting now!");_startSignal_.countDown(); _// 发出启动信号_
_        doneSignal_.await(); _// 等待所有线程完成__        _System._out_.println("All threads have finished executing.");}
}

死锁

public class DeadlockExample {// 创建两个资源
private static final Object _resourceOne _= new Object();
private static final Object _resourceTwo _= new Object();public static void main(String[] args) {new Thread(() -> {synchronized (resourceOne) {System.out.println(Thread.currentThread().getName() + "locked resource1");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}synchronized (resourceTwo) {System.out.println(Thread.currentThread().getName() + "locked resource2");}}}, "Thread-A").start();new Thread(() -> {synchronized (resourceTwo) {System.out.println(Thread.currentThread().getName() + "locked resource2");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}synchronized (resourceOne) {System.out.println(Thread.currentThread().getName() + "locked resource1");}}}, "Thread-B").start();}}

多个线程同时争抢同一把锁,阻塞情况下唤醒指定线程

  • 自定义条件变量
  • 标志变量

自定义条件变量

public class CustomLockExample {private final Lock lock = new ReentrantLock();private final Condition conditionA = lock.newCondition();private final Condition conditionB = lock.newCondition();private void methodA() throws InterruptedException {lock.lock();try {System._out_.println("Thread A is waiting");conditionA.await();System._out_.println("Thread A is resumed");} finally {lock.unlock();}}private void methodB() throws InterruptedException {lock.lock();try {System._out_.println("Thread B is waiting");conditionB.await();System._out_.println("Thread B is resumed");} finally {lock.unlock();}}private void resumeA() {lock.lock();try {conditionA.signal();  _// Wake up one thread waiting on conditionA_
_            _System._out_.println("Signaled Thread A");} finally {lock.unlock();}}private void resumeB() {lock.lock();try {conditionB.signal();  _// Wake up one thread waiting on conditionB_
_            _System._out_.println("Signaled Thread B");} finally {lock.unlock();}}public static void main(String[] args) throws InterruptedException {CustomLockExample example = new CustomLockExample();Thread threadA = new Thread(() -> {try {example.methodA();} catch (InterruptedException e) {e.printStackTrace();}});Thread threadB = new Thread(() -> {try {example.methodB();} catch (InterruptedException e) {e.printStackTrace();}});threadA.start();threadB.start();Thread._sleep_(2000);  _// Pause to ensure threads reach wait state__        _example.resumeA();   _// Signal threadA_
_        _Thread._sleep_(2000);example.resumeB();   _// Signal threadB_
_    _}
}

标志变量

public class FlagBasedControl {private final Object lock = new Object();private volatile boolean isThreadAWake = false;private void methodA() throws InterruptedException {synchronized (lock) {while (!isThreadAWake) {System._out_.println("Thread A is waiting");lock.wait();}}System._out_.println("Thread A is resumed and resetting flag");isThreadAWake = false;  _// Reset the flag for next use    }_
_    _}private void resumeA() {synchronized (lock) {isThreadAWake = true;lock.notifyAll();  _// Wake up all threads, but only Thread A will proceed_
_            _System._out_.println("Signaled Thread A");}}public static void main(String[] args) throws InterruptedException {FlagBasedControl example = new FlagBasedControl();Thread threadA = new Thread(() -> {try {example.methodA();} catch (InterruptedException e) {Thread._currentThread_().interrupt();}});threadA.start();Thread._sleep_(2000);  _// Pause to ensure thread reaches wait state__        _example.resumeA();  _// Signal threadA_
_    _}
}

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

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

相关文章

Linux梦开始的地方

1.概率 经过C语言&#xff0c;数据结构&#xff0c;C的学习我们现在要开始学习Linux的学习了。我们学习Linux是从四部分来进行的&#xff1a; 1.Linux初识&#xff0c;Linux环境&#xff0c;Linux指令&#xff0c;Linux开发环境。 2.Linux系统。 3.Linux网络 4.MySQL Lin…

“二维前缀和”算法原理及模板

在学习本篇内容前建议先学习一下“一维前缀和” 一维前缀和 算法https://blog.csdn.net/czt230610/article/details/148012923?fromshareblogdetail&sharetypeblogdetail&sharerId148012923&sharereferPC&sharesourceczt230610&sharefromfrom_link接下来…

软件设计师CISC与RISC考点分析——求三连

一、考点分值占比与趋势分析&#xff08;CISC与RISC&#xff09; 综合知识分值统计表 年份考题数量分值分值占比考察重点2018111.33%指令特征对比2019111.33%控制器实现方式2020222.67%寄存器数量/流水线技术2021111.33%寻址方式对比2022222.67%指令复杂度/译码方式2023111.3…

顺 序 表:数 据 存 储 的 “ 有 序 阵 地 ”

顺 序 表&#xff1a;数 据 存 储 的 “ 有 序 阵 地 ” 线 性 表顺 序 表 - - - 顺 序 存 储 结 构顺 序 表 的 操 作 实 现代 码 全 貌 与 功 能 介 绍顺 序 表 的 功 能 说 明代 码 效 果 展 示代 码 详 解SeqList.hSeqList.ctest.c 总 结 &#x1f4bb;作 者 简 介&#xf…

网络安全深度解析:21种常见网站漏洞及防御指南

一、高危漏洞TOP 10 1. SQL注入(SQLi) 原理:通过构造恶意SQL语句突破系统过滤机制 典型场景: - 联合查询注入: union select 1,version(),3--+ - 布尔盲注:and (select substr(user(),1,1)=r) - 时间盲注:;if(now()=sysdate(),sleep(5),0)/ 防御方案: - 严格参数化查…

代码上传gitte仓库

把代码push上去就行

创建型:单例模式

目录 1、核心思想 2、实现方式 2.1 饿汉式 2.2 懒汉式 2.3 枚举&#xff08;Enum&#xff09; 3、关键注意事项 3.1 线程安全 3.2 反射攻击 3.3 序列化与反序列化 3.4 克隆保护 4、适用场景 1、核心思想 目的&#xff1a;确保一个类仅有一个实例 功能&#xff1a;…

副业小程序YUERGS,从开发到变现

文章目录 我为什么写这个小程序网站转小程序有什么坑有什么推广渠道个人开发者如何变现简单介绍YUERGS小程序给独立开发者一点小建议 我为什么写这个小程序 关注我的粉丝应该知道&#xff0c;我在硕士阶段就已经掌握了小程序开发技能&#xff0c;并写了一个名为“约球online”…

React路由(React学习笔记_09)

React路由 1,路由基础 现代的前端应用大多都是SPA(单页应用程序)&#xff0c;也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器的压力更小&#xff0c;所以更受欢迎。为了有效的使用单个页面来管理原来多个页面的功能&#xff0c;前端路由应运而生。 1, 安装…

2009-2025计算机408统考真题及解析

整理2009-2025 年计算机408统考真题及解析PDF 目录树&#xff1a; └── 2025考研计算机408统考真题及答案&#xff08;回忆版&#xff09;.pdf ├── 2009-2024计算机408真题解析 │ ├── 2009年计算机408统考真题解析.pdf │ ├── 2010年计算机408统考真题解析.pdf …

Mysql、Oracle、Sql Server、达梦之间sql的差异

1&#xff1a;分页查询 Sql Server&#xff1a; <bind name"startRow" value"(page - 1) * limit 1"/> <bind name"endRow" value"page * limit"/> SELECT *FROM (SELECT ROW_NUMBER() OVER (<if test"sortZd!…

SQL Server 常用函数

一、字符串处理函数 1. CONCAT&#xff1a;拼接字符串 语法&#xff1a;CONCAT(string1, string2, ..., stringN) 实例&#xff1a; SELECT CONCAT(Hello, , World) AS Result; 输出&#xff1a; Result ------------- Hello World 2. SUBSTRING&#xff1a;截取子字符串 …

【通用大模型】Serper API 详解:搜索引擎数据获取的核心工具

Serper API 详解&#xff1a;搜索引擎数据获取的核心工具 一、Serper API 的定义与核心功能二、技术架构与核心优势2.1 技术实现原理2.2 对比传统方案的突破性优势 三、典型应用场景与代码示例3.1 SEO 监控系统3.2 竞品广告分析 四、使用成本与配额策略五、开发者注意事项六、替…

ABP vNext 多租户系统实现登录页自定义 Logo 的最佳实践

&#x1f680; ABP vNext 多租户系统实现登录页自定义 Logo 的最佳实践 &#x1f9ed; 版本信息与运行环境 ABP Framework&#xff1a;v8.1.5.NET SDK&#xff1a;8.0数据库&#xff1a;PostgreSQL&#xff08;支持 SQLServer、MySQL 等&#xff09;BLOB 存储&#xff1a;本地…

FastDFS分布式文件系统架构学习(一)

FastDFS分布式文件系统架构学习 1. FastDFS简介 FastDFS是一个开源的轻量级分布式文件系统&#xff0c;由淘宝资深架构师余庆设计并开发。它专为互联网应用量身定制&#xff0c;特别适合以中小文件&#xff08;如图片、文档、音视频等&#xff09;为载体的在线服务。FastDFS不…

基于单片机的防盗报警器设计与实现

标题:基于51单片机的防盗报警器设计 内容:1.摘要 本文围绕基于51单片机的防盗报警器设计展开。背景在于现代社会安全需求不断提高&#xff0c;传统防盗方式存在诸多不足。目的是设计一款成本低、可靠性高且易于使用的防盗报警器。方法上&#xff0c;以51单片机为核心控制单元&…

IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 LiteOS Studio + GCC + JLink

文章目录 概述LiteOS Studio不推荐&#xff1f;安装和使用手册呢?HCIP实验的源码呢&#xff1f; 软件和依赖安装软件下载软件安装插件安装依赖工具-方案2依赖工具-方案1 工程配置打开或新建工程板卡配置组件配置编译器配置-gcc工具链编译器配置-Makefile脚本其他配置编译完成 …

【高斯拟合最终篇】Levenberg-Marquardt(LM)算法

Levenberg-Marquardt(LM)算法是一种结合高斯-牛顿法和梯度下降法的优化方法,特别适合非线性最小二乘问题,如高斯函数拟合。它通过引入阻尼因子(damping factor)平衡高斯-牛顿法的快速收敛和梯度下降法的稳定性。以下是基于之前的 gaussian_fit.py,加入 LM 算法实现高斯拟…

信道编码技术介绍

信息与通信系统中的编码有4 种形式&#xff1a;信源编码、信道编码、密码编码和多址编码。 其中信道编码的作用是对信源经过压缩后的数据加一定数量受到控制的冗余&#xff0c;使得数据在传输中或接收中发生的差错可以被纠正或被发现&#xff0c;从而可以正确恢复出原始数据信息…

线性回归策略

一种基于ATR(平均真实范围)、线性回归和布林带的交易策略。以下是对该策略的全面总结和分析: 交易逻辑思路 1. 过滤条件: - 集合竞价过滤:在每个交易日的开盘阶段,过滤掉集合竞价产生的异常数据。 - 价格异常过滤:排除当天开盘价与最高价或最低价相同的情况,这…