多线程猜数问题
题目:线程 A 生成随机数,另外两个线程来猜数,线程 A 可以告诉猜的结果是大还是小,两个线程都猜对后,游戏结束,编写代码完成。
一、Semaphore
多个线程可以同时操作同一信号量,由此实现线程同步。
public class Main {private static Semaphore s1 = new Semaphore(0);private static Semaphore s2 = new Semaphore(0);// 待判断的线程private static Queue<Semaphore> judgeQueue = new LinkedList<>();// 保存线程猜的数private static Map<Semaphore, Integer> guessMap = new ConcurrentHashMap<>();// 保存判断结果private static Map<Semaphore, Integer> resMap = new ConcurrentHashMap<>();// 保存猜数线程二分过程中的左右边界private static Map<Semaphore, Pair<Integer, Integer>> edgeMap = new ConcurrentHashMap<>();private static Set<Semaphore> set = new HashSet<>();public static void main(String[] args) {new Thread(Main::judge, "判断线程").start();new Thread(() -> guess(s1), "猜线程1").start();new Thread(() -> guess(s2), "猜线程2").start();}private static void judge() {System.out.println("开始猜数!");int num = ThreadLocalRandom.current().nextInt(100);System.out.printf("要猜的数是 %d\n", num);set.add(s1);set.add(s2);s1.release();s2.release();while (true) {while (!judgeQueue.isEmpty()) {Semaphore s = judgeQueue.poll();Integer guessNum = guessMap.get(s);if (guessNum != null) {if (guessNum > num) {resMap.put(s, 1);} else if (guessNum < num) {resMap.put(s, 2);} else {resMap.put(s, 0);}s.release();} else {}}if (set.isEmpty()) {System.out.println("所有线程猜数完成!\n");break;}}}private static void guess(Semaphore s) {Pair<Integer, Integer> edge = new Pair<>(0, 100);edgeMap.put(s, edge);int guess = 0;while (true) {try {s.acquire();guess = guessNum(guess, s);if (guess != -1) {guessMap.put(s, guess);judgeQueue.add(s);} else {System.out.printf("%s 猜数成功!\n", Thread.currentThread().getName());set.remove(s);break;}} catch (InterruptedException e) {throw new RuntimeException(e);}}}private static int guessNum(int guess, Semaphore s) {Pair<Integer, Integer> pair = edgeMap.get(s);if (resMap.containsKey(s)) {int res = resMap.get(s);// 1 表示猜大了if (res == 1) {edgeMap.put(s, new Pair<>(pair.getKey(), guess - 1));} else if (res == 2) {edgeMap.put(s, new Pair<>(guess + 1, pair.getValue()));} else {// 猜中了return -1;}guess = (pair.getKey() + pair.getValue()) / 2;} else {guess = ThreadLocalRandom.current().nextInt(100);}System.out.printf("%s 猜的数是:%s\n", Thread.currentThread().getName(), guess);return guess;}
}
暂时没想到更好的解法,也欢迎大家指教。
相关文章:
多线程猜数问题
题目:线程 A 生成随机数,另外两个线程来猜数,线程 A 可以告诉猜的结果是大还是小,两个线程都猜对后,游戏结束,编写代码完成。 一、Semaphore 多个线程可以同时操作同一信号量,由此实现线程同步…...
Ubuntu环境安装
1. 安装gcc、g和make sudo apt update sudo apt install build-essential 2. 安装cmake ubuntu安装cmake的三种方法(超方便!)-CSDN博客 3. 安装ssh sudo apt-get install libssl-dev...
【家政平台开发(6)】筑牢家政平台安全防线:全方位隐私与安全需求解析
本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析,剖析家政行业现状、挖掘用户需求与梳理功能要点,到系统设计阶段的架构选型、数据库构建,再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化…...
Python数据类型-list
列表(List)是Python中最常用的数据类型之一,它是一个有序、可变的元素集合。 1. 列表基础 创建列表 empty_list [] # 空列表 numbers [1, 2, 3, 4, 5] # 数字列表 fruits [apple, banana, orange] # 字符串列表 mixed [1, hello, 3.14, True] # 混合类型…...
SpringBoot工程如何考虑优化使其视频请求更流畅
为了优化Spring Boot以提升前端视频读取的流畅性,可以从以下几个关键方向入手: 1. 分块传输与HTTP范围请求(Range Requests) 视频播放通常需要支持随机跳转进度,需确保后端正确处理HTTP Range头,实现按需传…...
如何使用cpp操作香橙派GPIO --使用<wiringPi.h>
香橙派是国产SBC ,对标树莓派。不过国内的开发环境确实挺惨的,没多少帖子讨论。楼主决定从今天起,不定期更新香橙派的教程。 今天的教程是如何使用香橙派下载wiringOP 并使用CPP操作GPIO 操作GPIO 下载wiringPi 检查git 版本克隆wiringPi…...
IP(Internet Protocol,互联网协议)
IP(Internet Protocol,互联网协议)地址是网络通信的核心标识,其作用可概括为以下关键点: 1. 核心作用 设备唯一标识 为联网设备(电脑、手机、服务器等)提供全球唯一的逻辑地址,确保数…...
nacos-sdk-go v2.29 中一个拼写错误,我定位了3个小时 ……
文章目录 问题背景问题现象问题定位解决方案经验总结 问题背景 今天在给项目增加服务注册和发现功能时,选择了 nacos 作为服务注册中心。在使用 nacos-sdk-go v2.29 版本进行开发时,遇到了一个令人啼笑皆非的问题,足足花了3个小时才找到原因。 问题现象 在实现服务订阅通知功…...
Linux中的文件寻址
Linux的层级结构 在Linux中一切皆文件 其中 要注意在命令行中看实际选择写哪一种路径 相对路径 绝对路径名称的简写,省略了用户当前所在的系统位置此名称只有在管理当前所在系统目录中子文件时才能使用系统中不以/开有的文件名称都为相对路径在程序操作时会自动…...
vue省市区懒加载,用el-cascader 新增和回显
el-cascader对于懒加载有支持方法,小难点在于回显的时候,由于懒加载第一次只有一层,所以要根据选中id数组一层层的加载。 子组件 <template><el-cascaderref"cascaderRef"v-model"selectedValue":props"…...
静态时序分析:时钟标记(作为数据使用的时钟)及其分析方式
相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 引言 一般情况下,设计中的时钟路径和数据路径是严格区分开的:时钟路径即从时钟源对象(时钟定义点)到触发器的时钟…...
AI学习记录-QWQ32b太强了
业务理解能力爆表,指令遵循能力极强,才32b成本极低,大量的公司的项目可以嵌入到自己的项目当中了,再fineture一下,以后不上AI的系统都卖不出去了。 试验1 输出 试验2: 输出...
【奇点时刻】GPT-4o新生图特性深度洞察报告
以下报告围绕最新推出的「GPT4o」最新图像生成技术展开,旨在让读者从整体层面快速了解其技术原理、功能亮点,以及与其他常见图像生成或AI工具的对比分析,同时也会客观探讨该技术在应用过程中可能遇到的挑战与限制。 1. 技术背景概述 GPT4o新…...
STM32 FATFS - 在spi的SD卡中运行fatfs
参考文章 STM32 CubeMX 硬件SPI SD卡 FATFS_stm32cubemx fatfs-CSDN博客 例程地址:STM32FatFS: 基于stm32的fatfs例程,配合博客文章 基于野火STM32MINI开发板 STM32配置 系统模式配置 输出串口配置 SPI配置 使用全双工模式,禁用硬件…...
我的世界进阶模组开发教程——地形生成(1)
找到mc的屎山代码,找到net.minecraft.world.level.levelgen包,我们来看看mc是如何完成地形生成的 SurfaceRules 代码结构与核心功能解析 该代码是 Minecraft 世界生成模块中地表规则(SurfaceRules)的核心实现,用于控制地形表面的方块生成逻辑。以下从多角度进行拆解分析…...
FreeCAD傻瓜教程-装配体Assembly的详细使用过程
源起: 看了官方的教程说明,感觉太过简单,好多细节没有体现,且该部分的翻译还没有。这里是做个记录,对使用过程中的细节进行图文说明,以方便真正的新手能够快速应用,制作出自己的零件,…...
Linux快速安装docker和docker-componse步骤
在 CentOS 7 上安装 Docker 和 Docker Compose 的步骤如下: 1. 安装 Docker 1.1. 更新系统 首先,确保你的系统是最新版本: sudo yum update -y1.2. 安装必要的包 安装 yum-utils,这是管理 YUM 源的工具: sudo yu…...
数字电子技术基础(三十七)——利用Multisim软件实现16线-4线编码器和4线-16线译码器
1 利用Multisim软件来实现16线-4线编码器 在之前的博客中完成了利用Multisim软件实现8线-3线优先编码器,现在使用Multisim软件来实现16线-4线编码器,其原理图如下所示: 使用字发生器来实现16线-4线编码器,器件选择: …...
02_MySQL安装及配置
文章目录 一、下载二、安装及配置2.1、选择安装类型2.2、检查需要的依赖2.3、安装2.4、配置2.4.1、配置类型和网络2.4.2、配置账户和角色2.4.3、配置Windows服务2.4.4、让配置生效 2.5、验证是否安装成功 三、卸载3.1、运行MySQL安装工具3.2、卸载及清理3.3、卸载之后的检查工作…...
Windows11,微软软件(VSCODE/EDG)错误登录,0x80190001错误
修改网络设置 运行以下命令,打开网络共享中心 Start-Process "control.exe" -ArgumentList "/name Microsoft.NetworkAndSharingCenter" 点击左下角的 选项 TLS 1.1 1.2 1.3 这三个选项 1.0 不建议启用,不安全 1.1 可以不用启用…...
WPF 浅述IsHitTestVisible属性
WPF 浅述IsHitTestVisible属性 IsHitTestVisible 属性是 WPF 中一个非常重要的属性,它决定了一个控件是否可以作为 hit test 的一部分被检测到。理解这个属性对于处理交互事件(如鼠标点击、触摸等)非常重要。 IsHitTestVisible 属性的含义&am…...
力扣刷题-热题100题-第29题(c++、python)
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/?envTypestudy-plan-v2&envIdtop-100-liked 计算链表长度 对于链表,难的就是不知道有多少元素ÿ…...
NLP高频面试题(三十)——LLama系列模型介绍,包括LLama LLama2和LLama3
本文深入介绍Meta推出的LLama系列模型,包括LLama、LLama2和LLama3,探讨了它们的技术创新、应用场景以及对大语言模型发展的重要推动作用。通过系统地回顾各代模型的进化过程,分析其核心特性与技术亮点,为读者提供全面且深入的理解…...
torch.nn.Conv2d介绍——Pytorch中的二维卷积层
torch.nn.Conv2d是torch.nn模块中的二维卷积层类,用于构建神经网络中的二维卷积层。 1、基本语法 torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue, padding_modezeros, deviceNone, dtypeNone)将 2D …...
阻止上传可执行程序
点击工具中的文件服务器资源管理器 、然后点击文件屏蔽管理中的文件屏蔽,然后导入目标文件选择要限制的属性即可...
DirectX修复工具免费版下载安装教程(附安装包)
文章目录 前言一、DirectX修复工具免费版介绍二、DirectX修复工具免费版安装教程1. 下载安装包2. 解压文件3. 以管理员身份运行4. 开始检测与修复5. 查看修复详情 前言 本教程主要介绍的是DirectX修复工具免费版下载安装教程,帮您轻松解决 DirectX 相关问题。 一、…...
UE5学习笔记 FPS游戏制作33 游戏保存
文章目录 核心思想创建数据对象创建UIUI参数和方法打开UI存档文件的位置可以保存的数据类型 核心思想 UE自己有保存游戏的功能,核心节点,类似于json操作,需要一个数据类的对象来进行保存和读取 创建存档 加载存档 保存存档 创建数据对象…...
Git与SVN的区别以及各自的优势
前言:版本控制的诞生与意义 在软件开发的漫长历程中,代码的迭代与协作始终是核心挑战。从早期的“文件夹版本”到现代的分布式系统,版本控制系统(VCS)的进化史,本质上是人类对协作效率与数据安全的不懈追求…...
PipeWire 音频设计与实现分析三——日志子系统
日志子系统 PipeWire 的日志子系统的设计分为多个层次。PipeWire 用 struct spa_log 对象描述日志组件,用 struct spa_log_methods 对象描述日志组件打印各层级日志的多个方法。PipeWire 为日志子系统添加了 topic 机制,不同文件中的日志按功能以不同的…...
TypeScript vs. JavaScript:技术对比与核心差异解析
引言 在 Web 前端开发领域,JavaScript(JS)长期占据主导地位,但随着项目复杂度的提升,开发者逐渐面临维护性差、协作困难等问题。TypeScript(TS)作为 JavaScript 的超集,通过静态类型…...
