Day30 线程安全之窗口售票问题(含代码)

news2024/11/19 18:21:07

Day30 线程安全之窗口售票问题(含代码)

一、需求:

铁道部发布了一个售票任务,要求销售1000张票,要求有3个窗口来进行销售,
请编写多线程程序来模拟这个效果( 注意:使用线程类的方式解决该需求)

 		窗口001正在销售第1张票
 		窗口001正在销售第2张票
 		窗口002正在销售第3张票
		 。。。
     	窗口002正在销售第1000张票
 		窗口002票已售完
 		窗口001票已售完
 		窗口003票已售完

二、问题一

1、问题一:

三个窗口各卖1000张票,一共卖了3000张

2、相关代码:

package com.qf;

public class MyThread extends Thread {
	 public MyThread(String name) {
		// TODO 自动生成的构造函数存根
		 super(name);
	}
	@Override
	public void run() {
		
		// TODO 自动生成的方法存根
		int allTicket=1000;
		int curTicket=0;
		while (curTicket<allTicket) {
			curTicket++;
			System.out.println("窗口"+Thread.currentThread().getName()+"正在出售"+curTicket+"第几张票");
			
		}
	}
}
public class Test01 {
	public static void main(String[] args) {
		MyThread myThread1  = new MyThread("001");
		MyThread myThread2  = new MyThread("002");
		MyThread myThread3  = new MyThread("003");
		myThread1.start();
		myThread2.start();
		myThread3.start();
	}
}

出现的问题:

在这里插入图片描述

3、出现原因:

allTicket和curTicket是run方法的局部变量,三个线程抢到CPU资源后,都会调用run方法,run方法被调用了3次,所以卖了3000张票。

4、解决方案:

将allTicket和curTicket设置为静态变量,让三个线程共享

三、问题二

1、问题二:

有些票没有卖,有些票卖了重票

2、相关代码:

package com.qf;

public class MyThread extends Thread {
	private static int allTicket=1000;
	private static int curTicket=0;
	 public MyThread(String name) {
		// TODO 自动生成的构造函数存根
		 super(name);
	}
	@Override
	public void run() {
		
		// TODO 自动生成的方法存根
		while (curTicket<allTicket) {
			curTicket++;
			System.out.println("窗口"+Thread.currentThread().getName()+"正在出售"+curTicket+"第几张票");
			
		}
	}
}
public class Test01 {
	public static void main(String[] args) {
		MyThread myThread1  = new MyThread("001");
		MyThread myThread2  = new MyThread("002");
		MyThread myThread3  = new MyThread("003");
		myThread1.start();
		myThread2.start();
		myThread3.start();
	}
}

出现问题:

在这里插入图片描述

3、出现原因:

当前线程抢到CPU资源后做了票的自增,但是还没来得及输出,时间片到了就退出CPU资源,然后其他线程抢到CPU资源了。

4、解决方案:

当前线程抢到CPU资源后,票的自增和输出执行完毕才能切换到其他线程运行 – 加锁

四、问题三

1、问题三:

多卖了票。

2、相关代码:

package com.qf;

public class MyThread extends Thread {
	private static int allTicket=1000;
	private static int curTicket=0;
	private static Object obj = new Object();
	 public MyThread(String name) {
		// TODO 自动生成的构造函数存根
		 super(name);
	}
	@Override
	public void run() {
		
		// TODO 自动生成的方法存根
		while (curTicket<allTicket) {
			synchronized (obj) {
				curTicket++;
				System.out.println("窗口"+Thread.currentThread().getName()+"正在出售"+curTicket+"第几张票");
			}
			
		}
	}
}
public class Test01 {
	public static void main(String[] args) {
		MyThread myThread1  = new MyThread("001");
		MyThread myThread2  = new MyThread("002");
		MyThread myThread3  = new MyThread("003");
		myThread1.start();
		myThread2.start();
		myThread3.start();
	}
}

出现问题:

在这里插入图片描述

3、出现原因:

curTicket到了临界点(999),三个线程都可以进判断,然后上锁。

4、解决方案:

在锁中再次判断。

完整代码

package com.qf;

public class MyThread extends Thread {
	private static int allTicket=1000;
	private static int curTicket=0;
	private static Object obj = new Object();
	 public MyThread(String name) {
		// TODO 自动生成的构造函数存根
		 super(name);
	}
	@Override
	public void run() {
		
		// TODO 自动生成的方法存根
		while (curTicket<allTicket) {
			synchronized (obj) {
				if(curTicket < allTicket){
					curTicket++;
					System.out.println("窗口" + Thread.currentThread().getName() + "正在销售第" + curTicket + "张票");
				}
				if(curTicket >= allTicket){
					System.out.println("窗口" +  Thread.currentThread().getName() + "票已经售完");
				}
			}
		}
	}
}
public class Test01 {
	public static void main(String[] args) {
		MyThread myThread1  = new MyThread("001");
		MyThread myThread2  = new MyThread("002");
		MyThread myThread3  = new MyThread("003");
		myThread1.start();
		myThread2.start();
		myThread3.start();
	}
}
 args) {
		MyThread myThread1  = new MyThread("001");
		MyThread myThread2  = new MyThread("002");
		MyThread myThread3  = new MyThread("003");
		myThread1.start();
		myThread2.start();
		myThread3.start();
	}
}

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

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

相关文章

数据库 06-04 恢复

01 一.事务故障 二.系统 三.磁盘 02. 重点是稳定存储器 组成

【IEEE STD 1801】——Introduction

Introduction 本标准的目的是提供便携、低功耗的设计规范&#xff0c;这些规范可以在整个电子系统设计、分析、验证和实现流程中与各种商业产品一起使用。 当电子设计自动化(EDA)行业在20世纪80年代开始创建用于指定、仿真和实现数字电子电路的功能规范的标准时&#xff0c;主…

当下鸿蒙开发热潮,大前端开发有没有必要搞!!!

鸿蒙到底好不好&#xff1f;要不要搞&#xff1f; Android开发反正目前工作感觉也不好找&#xff0c;即便是上海这样的大城市也难搞&#xff0c;人员挺饱和的。而且年前裁员的公司那么多&#xff0c;再看自己&#xff0c;年龄不是优势&#xff1b;技术不是优势&#xff0c;想想…

DHCP-PXE

Dynamic Host Configuration Protocol 动态主机配置协议 1.Selinux 调试为Permission 防火墙配置 搭建DHCP的主机必须有一个静态地址&#xff0c;提前配置好 安装DHCP软件 服务名为dhcpd DHCP地址分配四次会话&#xff0c; DISCOVERY发现 OFFER 提供 REQUEST 回应 A…

PHP实现nginxPhp错误日志提取统计工具(路径+错误行+报错信息+次数排序)

粘贴PHP错误日志内容(NGINX 下PHP网站错误日志)。 作用:提取PHP Warning/Notice:路径错误行报错信息按出现次数排序。 以上已满足本人自己LNMP环境的调试需求&#xff0c;其他环境自己评估是否可用。 <?php //整理与分享&#xff1a;yujianyue<15058593138qq.com> $…

国家开放大学电大《钢结构》形考任务答案

电大搜题 多的用不完的题库&#xff0c;支持文字、图片搜题&#xff0c;包含国家开放大学、广东开放大学、超星等等多个平台题库&#xff0c;考试作业必备神器。 公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#x…

腾讯云-域名注册购买实名流程

1&#xff0c;注册并完成实名腾讯云账号 账号实名认证和后续要完成的域名实名认证应为同一主体单位。否则域名实名会不通过 参考链接 腾讯云账号实名 – 易极赞自助建站 2&#xff0c;进入腾讯云域名注册购买地址 推荐购买com&#xff0c;cn&#xff0c;net主流域名&#xf…

LabVIEW深度学习

目录 一、配置环境1.1、显卡选择1.2、下载显卡驱动1.3、下载并安装Anaconda1.4、配置Anaconda软件包下载服务器1.5、配置虚拟环境tf_gpu1.6、安装vscode1.7、安装tensorflow1.8、下载安装Git1.9、安装TensorFlow Object Detection API框架1.10、安装依赖的python软件包1.11、配…

Centos7下docker安装jenkins【使用docker-compose图文教程】

个人记录 前置条件&#xff1a;安装Docker与Docker-compose Centos7安装Docker与Docker-compose【图文教程】 查看jenkins最新的版本 https://www.jenkins.io/download/ 配置docker-compose.yml vim docker-compose.yml按i进行编辑模式&#xff0c;粘贴如下内容。把image里…

After Effects 2024:创意无界,想象成真mac/win版

在数字艺术飞速发展的今天&#xff0c;After Effects 2024已经站在了视觉特效和动态图形设计的最前沿。这款软件不仅继承了之前版本的强大功能&#xff0c;更在细节和效率上进行了全方位的优化和升级。 After Effects 2024软件获取 After Effects 2024为用户提供了更加丰富的特…

A - Penalty Kick

A - Penalty Kick 我又又又回来啦 题目&#xff1a; Problem Statement Takahashi will have N N N penalty kicks in a soccer match. For the i i i-the enalty kick, he will fail if i i i is a multiple of 3 3 3, and succeed otherwise . . . Print the resul…

拦截器抛出异常无法被全局异常处理器捕获问题

文章目录 基本说明问题描述问题原因解决方法前端执行的所有请求都通过Controller&#xff0c;而不是直接访问html定义一个/error路径的方法 总结 基本说明 我的前后端项目是放在一起的&#xff0c;前后端都是由springMVC进行控制&#xff0c;但是现在我在拦截器的preHandle方法…

c# wpf LiveCharts 简单试验2

1.概要 1.1 说明 1.2 要点 1.2.1 添加命名控件 xmlns:lvc"clr-namespace:LiveCharts.Wpf;assemblyLiveCharts.Wpf" 1.2.2 图片控件 <lvc:CartesianChart Name"chart" LegendLocation"Right"/> 1.3 代码文件引用 using LiveCharts…

循环神经网络:揭秘长期记忆的魔法之源

在人工智能和机器学习领域&#xff0c;循环神经网络&#xff08;Recurrent Neural Networks&#xff0c;简称RNN&#xff09;以其独特的架构和机制&#xff0c;在处理序列数据方面展现出了强大的能力。特别值得一提的是&#xff0c;RNN能够学习到长期的记忆&#xff0c;这使得它…

综测仪MT8862A控制方法

实现自动化控制&#xff0c;本次为大家讲解综测仪MT8862A的控制逻辑。 新建底层控制逻辑 在文件basis_contorl.py中写入仪器控制底层代码&#xff0c;代码如下&#xff1a; import tkinter.messagebox import pyvisaclass InstrumentControl(object):inst Nonedef __init__(…

利用Flutter混淆工具提高应用的反编译难度

在移动应用开发中&#xff0c;保护应用代码安全至关重要。Flutter 提供了简单易用的混淆工具&#xff0c;帮助开发者在构建 release 版本应用时有效保护代码。本文将介绍如何在 Flutter 应用中使用混淆&#xff0c;并提供了相关的操作步骤和注意事项。 &#x1f4dd; 摘要 本…

C# 委托的基础应用

一、Action 和 Func 的使用。 二、自定义委托&#xff1a; 完整的使用代码示例&#xff1a; 三、委托的一般使用 模板方法&#xff1a; 回调方法&#xff0c;在模板方法的基础上进行添加。

使用向量检索和rerank 在RAG数据集上实验评估hit_rate和mrr

文章目录 背景简介代码实现自定义检索器向量检索实验向量检索和rerank 实验 代码开源 背景 在前面部分 大模型生成RAG评估数据集并计算hit_rate 和 mrr 介绍了使用大模型生成RAG评估数据集与评估&#xff1b; 在 上文 使用到了BM25 关键词检索器。接下来&#xff0c;想利用向…

Filter

概念&#xff1a;Filter表示过滤器&#xff0c;是JavaWeb三大组件&#xff08;Servlet,Filter&#xff0c;Listener&#xff09;之一 过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。 过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;权限控…

元宇宙虚拟空间的场景渲染(五)

前言 该文章主要讲元宇宙虚拟空间的场景渲染&#xff0c;基本核心技术点&#xff0c;不多说&#xff0c;直接引入正题。 场景渲染 下面第二个图中的代码是一个循环渲染逻辑&#xff0c;首先getDelta 获取2次时间的时间间隔&#xff0c;requestAnimationFrame请求我们的一个动…