LinkedBlockingQueue 模拟抢房间座位问题

问题描述: 假设有10个房间,每个房间有5个座位。这些座位可能是空的,也可能坐着人,房间外面有大量   的人等待空位,房间内的人可能随时离开, 因此要不停的扫描房间空位一旦有空的就抢座上去。

博客原文地址  http://sprite311.iteye.com/blog/2033655

 

解决思路:

1涉及到多线的安全问题,调查到LinkedBlockingQueue 是java.util.concurrent包下的线程安全的阻塞 队列,用之;

2房间里的座位类似生产者的产品;

3 一个队列模拟一个房间,涉及到多个房间使用队列数组来模拟;

4生产者向队列里放数据(人进入房间)使用offer()方法而不使用put()方法,因为put条件不满足时是阻塞的;

5使用Random来模拟人随机的去某个房间排队;

 

代码:

             

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 
 * 
 * 描述: 假设有10个房间,每个房间有5个座位。这些座位可能是空的,也可能坐着人,房间外面有大量的人等待空位,房间内的人可能随时离开,
 *       因此要不停的扫描房间空位一旦有空的就抢座上去。 
 * 创建人:田超 
 * 创建时间:2014-3-19 下午4:34:32
 * blog:http://sprite311.iteye.com/
 * 
 */
public class MultiRoomSeatCompetition {
	private static int roomCount = 10;

	public static void main(String[] args) {
		// 所有房间的数组集合
		LinkedBlockingQueue<String>[] roomArray = new LinkedBlockingQueue[roomCount];
		for (int i = 0; i < roomCount; i++) {
			roomArray[i] = new LinkedBlockingQueue<String>(5);
		}
		System.out
				.println("创建了" + roomArray.length + "个房间-------------------。");
		// System.out.println(roomArray[0].size());
		Consumer c11 = new Consumer("消费者01号", roomArray, roomCount);

		Producer p11 = new Producer("生产者01号", roomArray, roomCount);
		Producer p22 = new Producer("生产者02号", roomArray, roomCount);
		Producer p33 = new Producer("生产者03号", roomArray, roomCount);
		Producer p44 = new Producer("生产者04号", roomArray, roomCount);
		Producer p55 = new Producer("生产者05号", roomArray, roomCount);
		Producer p66 = new Producer("生产者06号", roomArray, roomCount);
		Producer p77 = new Producer("生产者07号", roomArray, roomCount);
		Producer p88 = new Producer("生产者08号", roomArray, roomCount);
		Producer p99 = new Producer("生产者09号", roomArray, roomCount);

		ExecutorService service = Executors.newCachedThreadPool();

		service.submit(c11);

		service.submit(p11);
		service.submit(p22);
		service.submit(p33);
		service.submit(p44);
		service.submit(p55);
		service.submit(p66);
		service.submit(p77);
		service.submit(p88);
		service.submit(p99);
	}
}

/**
 * 生产者 (排队的人 :类似生产者的产品)
 */
class Producer implements Runnable {
	private String pname;
	private LinkedBlockingQueue[] roomArray;
	private int roomCount;

	public Producer(String pname, LinkedBlockingQueue[] roomArray, int roomCount) {
		this.pname = pname;
		this.roomArray = roomArray;
		this.roomCount = roomCount;
	}

	public void run() {
		try {
			while (true) {
				UUID productID = UUID.randomUUID();
				Random r = new Random();
				int i = r.nextInt(roomCount);
				boolean isEnter = roomArray[i].offer(String.valueOf(productID));
				if (isEnter) {
					System.out.println("在" + i + "号房排队的" + productID + "已经进入"
							+ i + "号房,房间里现在有" + roomArray[i].size() + "个人");
				}
				// Thread.sleep(500);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
}

/**
 * 消费者 :将房间里的人取走的线程
 */
class Consumer implements Runnable {
	private String cname;
	private LinkedBlockingQueue[] roomArray;
	private int roomCount;

	public Consumer(String cname, LinkedBlockingQueue[] roomArray, int roomCount) {
		this.cname = cname;
		this.roomArray = roomArray;
		this.roomCount = roomCount;
	}

	public void run() {
		try {
			while (true) {
				Random r = new Random();
				int i = r.nextInt(roomCount);
				String product = (String) roomArray[i].take();
				System.out.println(product + "已经离开了" + i + "号房,房间里现在有"
						+ roomArray[i].size() + "个人");
				Thread.sleep(5000);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

 

存在的问题:假如房间满的,某个人没能进去,那他就被抛弃了--!
我觉得可以维护一个集合,存进入房间失败的人,集合为空才生产新的人

                 

SpringBoot+Vue+MySQL 高校学科竞赛平台 完整可运行版(源码+文档) 本项目基于SpringBoot+Vue+MySQL构建高校学科竞赛管理平台,覆盖学生、教师、领队教师、管理员四大角色,实现竞赛发布、报名、刷题、评分、公示等全流程闭环管理。系统架构清晰,技术主流,配套完整源码、数据库脚本、万字论文、开题报告、答辩PPT及部署文档,支持一键运行,适用于毕业设计、课程设计及院系二次开发,真正实现“开箱即用”。 阅读详情

相关推荐

UOS系统手动添加1920x1080分辨率:xrandr命令详解与持久化配置

本文详细介绍了在UOS系统中使用xrandr命令手动添加1920x1080分辨率的方法。针对系统设置中缺失该选项的常见问题,文章提供了从识别显示设备、使用cvt生成模式、添加并切换分辨率,到通过修改.profile文件实现持久化配置的完整步骤。同时涵盖了虚拟机环境、设备名识别及排错等进阶内容,帮助用户彻底解决UOS分辨率配置难题。

weixin_29300931的博客 499

秒杀系统架构分析与实战

互联网正在高速发展,使用互联网服务的用户越多,高并发的场景也变得越来越多。电商秒杀和抢购,是两个比较典型的互联网高并发场景。虽然我们解决问题的具体技术方案可能千差万别,但是遇到的挑战却是相似的,因此解决问题的思路也异曲同工。

Websites 1531

手把手教你用STM32F103C8T6驱动CLRC663国产NFC模块(兼容A/B/F/15693卡)

本文详细介绍了如何使用STM32F103C8T6驱动国产CLRC663 NFC模块,支持ISO14443A/B、Felica和ISO15693协议。从硬件设计、协议适配到状态监控,提供完整的工程实现方案,适用于智能门锁、支付终端等应用场景。

weixin_30689307的博客 445

高并发编程之LinkedBlockingQueue讲解

一、LinkedBlockingQueue介绍 ①、LinkedBlockingQueue是一个单向链表实现的阻塞队列,先进先出的顺序。支持多线程并发操作。相比于数组实现的ArrayBlockingQueue的有界,LinkedBlockingQueue可认为是无界队列。多用于任务队列。 ②、LinkedBlockingQueue不同于ArrayBlockingQueue,它如果不指定容量,默认为...

weixin_42146366的博客 3631

相位相关匹配法的opencv C++实现

这一段就是PCIAM算法的核心了,计算两幅图像的峰值相关矩阵,也是完全按照matlab移植过来的,但是后面几行,是为了筛选一些不可能存在的情况,比如边缘处的完全重合,或者只有一行,或者一列重合等等情况,由于PCIAM算法在边缘处的响应值高,所以在一些场景下可能是一种干扰,所以进行了剔除,当然可以不剔除,就是对后期的峰值选取会有影响。头文件,以及各类函数,还有主函数,第一次独立的写这种分文件类型的项目,写的拉跨还请包涵,以及当然可以转成类的形式,但感觉有点小麻烦,后期再修改吧。

qq_43616651的博客 4263

使用Java实现CRC16 MODBUS 格式校验

CRC16校验,测试如下 String str = "a5 98 03 00 00 5f c6 0f 7c 40 78 06 09 46 dc 6e db 00 16 3e 12 5c 98 00 19 98 0e 10 03 06 09 46 dc 6e db 03 0b bf 5f c6 0f 7c 43 bd b9 61 ee 96 76 99"; 校验规则: /** * CRC16_CCITT:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结

weixin_45063710的博客 1314

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 286

3D点云修复实战:用PCN网络快速补全缺失的激光雷达数据(附代码)

本文详细介绍了PCN(Point Completion Network)网络在3D点云修复领域的实战应用。针对激光雷达数据常见的缺失问题,PCN通过端到端的深度学习架构,直接处理原始点云,实现由粗到精的快速补全。文章深入解析了其核心思想与编码器-解码器架构,并提供了完整的环境搭建、数据准备、模型实现、训练评估及在真实场景下的优化策略与代码示例,为自动驾驶、机器人等领域的开发者提供了高效的数据修复解决方案。

weixin_29041195的博客 392

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 346

树莓派 SPI操作

扩展板配备一款0.96inch,128864分辨率的oled显示屏,通过SPI控制,先上显示效果图。由于程序过长,在这里我就不把代码全部贴出来了,只是简单讲解一下spi的操作函数。管脚如下如所有,左边方框的管脚分别为MOSI MISO SCLK,左边CE0,CE1为两个片选管脚,分别对应上图中的spidev0.0,spidev0.1两个设备。下载spidev库,复制到树莓派,并行运行如下命令解压安装。spi设备,此处设备为/dev/spi-decv0.0。在/dev路径下面,我们可以发现两个spi设备。

weixin_46529898的博客 914

ADG同步性能优化:如何正确配置standby redolog避免WAIT_FOR_LOG状态

本文深入剖析了Oracle ADG(Active Data Guard)同步中常见的WAIT_FOR_LOG状态,指出其根源在于Standby Redo Log(SRL)配置不当。文章提供了从诊断到优化的完整实践指南,重点阐述了SRL大小匹配、组数充足等黄金配置法则,帮助架构师从根本上避免同步延迟,实现稳定高效的实时数据同步。

weixin_29200485的博客 334

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 128

QT C++ AI棉花智能变量灌溉工上位机(信创完整版)

北斗履带灌溉机器人/田间分区电磁阀基站 → 多层土壤温湿度/盐分EC传感器实时采集墒情 → 双目AI视觉扫描棉田长势、病苗分布 → AI融合**生育期+土壤墒情+盐分+棉株长势**计算变量灌溉定额、水肥配比、灌溉时长 → 分区电磁阀/变频水泵变量供水,病弱苗地块减量、干旱地块增量;墒情、盐分、长势多因子闭环修正灌水量;多层土壤含水率(0–10/20–40/40–80cm)、土壤EC盐分、土壤温度、空气温湿度、蒸发量、北斗地块坐标、管道水压、水肥罐液位、分区流量计、水泵电机负载、滴灌带压力反馈。

寒寒豆豆软件公司的博客 186

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 198

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

LeetCode Hot 100 二叉树专题(二)3 题(Java)

本篇文章共 3 题:543. 二叉树的直径、102. 二叉树的层序遍历、108. 将有序数组转换为二叉搜索树。 每道题都统一按「① 题目分析 & 解题思路 → ② 常见解法(附代码)及讲解 → ③ 知识点总结」的顺序组织;代码使用 Java 编写,节点定义沿用 LeetCode 默认的 TreeNode。

2401_88612756的博客 365

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端

上一篇讲了 MCP 的概念:标准协议、三大角色、M+N 替代 M×N。

nice_lcj520的博客 499

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

JDK 下载安装:装完 Java 提示「不是内部或外部命令」?环境变量没配

JDK 是写 Java 程序必须装的东西。它包含运行 Java 的虚拟机(JRE)和编译 Java 的编译器(javac)——装了它,能跑、.java文件能编译成可执行程序。免费,学习和小规模生产都不花钱。

科小怪的博客 634

java框架大全

java框架大全

qq_39326137的博客 183

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 360

SecureRandom做随机源,这个Java随机字符串工具类有3个方法

本文分享一款JDK17环境下的Java随机字符串工具类,内置3个开箱即用的方法,全部采用SecureRandom加密安全随机源,不存在弱随机、可预测、取模偏差等问题。工具类支持默认62字符集随机串、纯数字随机串、自定义字符集随机串三种生成模式,支持Unicode码点级别的字符集处理,兼容Emoji等增补字符,边界处理严格,异常信息明确,适合验证码、邀请码、盐值、随机口令、短链码等场景,源码可直接复制使用。

Java后端 | AI智能体应用实战派 | 电脑技能行家 298

IDEA 简介:从零认识 IntelliJ IDEA

IDEA 全称,是由 JetBrains 公司开发的一款主流 Java 集成开发环境(IDE)。它集代码编辑、编译、调试、测试、版本控制、构建管理等功能于一体,被大量 Java 开发者视为日常开发的首选工具。所谓 IDE(Integrated Development Environment,集成开发环境),就是把写代码所需的各类工具整合到同一个界面中。相比只用文本编辑器加命令行编译,IDE 能显著减少重复操作,让开发者把精力集中在业务逻辑上。

ztI10的博客 151

Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

【代码】Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

m0_64476639的博客 328

ubuntu安装hadoop系统

本文详细介绍了基于VMware克隆虚拟机搭建三节点Hadoop分布式集群的全过程:使用同一Ubuntu镜像克隆出master、worker1、worker2三台虚拟机,依次配置主机名、固定IP(如192.168.82.10/11/12)、SSH服务及免密登录,确保节点间网络互通。随后安装Java,下载配置Hadoop并分发至各节点,最终初始化启动集群,验证其存储与计算功能,实现高效的大数据环境部署。

qq_43592674的博客 334

TRingBuffer两端都能增删(快递站版)

TRingBuffer 是一个支持两端增删、下标访问且容量动态增长的环形双端队列。它通过无符号索引的永不归零设计,利用减法自动模运算实现空满判断与元素计数,避免了传统环形缓冲浪费格子的问题。内部以票号(索引)标记首尾,扩容时重排元素为连续存储,保证 O(1) 操作与高缓存效率。虽不线程安全,但其高效性使其成为游戏开发中事件队列、命令缓冲等场景的理想选择。

u013768914的博客 227

Mac上装了最新版本的Android Studio,但是没找到jdk的设置选项也没找到jbr的目录

新版Android Studio(2025.3.1+)因三项变更导致常见问题:一、JDK设置移至“DaemonJVM criteria”,新项目默认自动探测或下载JDK;二、JBR目录改名为带版本号的jbr-21等,需进入.app/Contents/查看,或通过About窗口确认运行时;三、命令行缺adb因platform-tools未加入PATH,需在SDK Manager中勾选并配置~/.zshrc中的ANDROID_HOME及PATH。重装或清理残留可解决缺失问题,切勿手动设JAVA_HOME或安装冲

Programming is a highly artistic endeavor 352
上一篇: java多线程最基础的问题及答案(译)
下一篇: java.util.vector 多线程问题及java.util.concurrent包下并发安全原理
tianchao_
博客等级 码龄16年 2粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值