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

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();
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LABVIEW--正弦+高斯噪声信号及滤波

前面板信号 后面板 LABVIEW源程序链接&#xff1a;https://pan.baidu.com/s/11B-75i4fHZwWQyjxn9yCyQ?pwd7tfj 提取码&#xff1a;7tfj

设计模式之建造者模式:灵活可扩展的对象创建过程

目录 一、什么是建造者模式 二、建造者模式的应用场景 三、建造者模式的优缺点 3.1. 优点 3.2. 缺点 四、建造者模式示例 4.1. 问题描述 4.2. 问题分析 4.3. 代码实现 五、建造者模式的另一种实现方式 六、总结 一、什么是建造者模式 建造者模式&#xff08;Builder…

WEBAPIS知识案例总结(续)

其他事件 页面加载事件 加载外部资源&#xff08;如图片&#xff0c;外联css和js等&#xff09;加载完毕时触发的事件有时候需要等页面资源全部处理完之后做一些事情老代码喜欢把script写在head中&#xff0c;这时候直接找dom元素找不到事件名&#xff1a;load监听页面所有资…

【热门话题】Stable Diffusion:本地部署教程

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Stable Diffusion&#xff1a;本地部署教程一、引言二、环境准备1. 硬件配置2. …

考研数学|怎样刷题更有效率?这些坑千万别踩!

考研数学刷题的这些困扰相信大部分的同学都是有的&#xff0c;为此我整理了一些提高考研数学刷题效率的方法和策略&#xff0c;希望能帮助你更有效地学习和解题。 首先要制定合理的刷题计划&#xff0c;首先遵循“教材→视频→全书或辅导讲义→习题集→真题→专项训练→模拟套…

vue项目开发实战案例

目录 项目概述 1. 项目初始化 2. 商品展示 3. 购物车管理 4. 订单处理 5. 路由管理 6. 样式和交互优化 7. 部署和测试 总结 Vue.js 是一种流行的前端 JavaScript 框架&#xff0c;广泛应用于现代 Web 开发中。下面是一个简单的 Vue 项目开发实战案例&#xff0c;涵盖了…

C++的并发世界(七)——互斥锁

0.死锁的由来 假设有两个线程T1和T2&#xff0c;它们需要对两个互斥量mtx1和mtx2进行访问。而且需要按照以下顺序获取互斥量的所有权&#xff1a; -T1先获取mte1的所有权,再获取mt2的所有权。 -T2先获取 mtx2的所有权。再铁取 mtx1的所有权。 如果两个线程同时执行&#xff0c…

Redis主从复制、哨兵模式、Cluster集群

目录 一、Redis主从复制 1、主从复制介绍 2、主从复制原理 ​编辑 3、主从复制的作用 4.Redis主从复制实验搭建 1. 关闭防火墙和安装依赖环境 2. 解压安装包 3. 编译并安装到指定目录 4. 执行脚本文件 5. 做软连接 6. 启动redis并查看端口 7. 重启redis 8. 修改主…

秋招刷题4(动态规划)

1.购物单 import java.util.Scanner;public class Main {public static void main(String[] args){Scanner sc new Scanner(System.in);int N sc.nextInt();int m sc.nextInt();Goods[] goods new Goods[m];for(int i 0; i < m; i){goods[i] new Goods();}for(int i …

Matlab|含氢微网优化调度模型

目录 1 主要内容 模型示意图 目标函数 2 部分程序 3 程序结果 4 下载链接 1 主要内容 最近咨询含氢微网优化调度模型的同学较多&#xff0c;本次就分享一个高质量的源码资源。该程序方法复现《Simulation of design and operation of hydrogen energy utilization system…

数据生成 | Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成

数据生成 | Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成 目录 数据生成 | Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成生成效果基本描述模型描述程序设计参考资料 生成效果 基本描述 1.Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成&#xf…

揭秘动态内存管理,让你少走弯路!

1. 为什么要有动态内存分配 2. malloc和free 3. calloc和realloc 4. 常⻅的动态内存的错误 5. 动态内存经典笔试题分析 6. 柔性数组 7. 总结C/C中程序内存区域划分 正文开始&#xff1a; 1. 为什么要有动态内存分配 我们已经掌握的内存开辟⽅式有&#xff1a; int…

LeetCode---391周赛

题目列表 3099. 哈沙德数 3100. 换水问题 II 3101. 交替子数组计数 3102. 最小化曼哈顿距离 一、哈沙德数 简单的模拟题&#xff0c;代码如下 class Solution { public:int sumOfTheDigitsOfHarshadNumber(int x) {int s 0, tmp x;while(tmp){stmp%10;tmp/10;}return x…

Redis 5种数据结构常用命令

文章目录 1 字符串2 哈希3 列表4 集合5 有序集合 1 字符串 命令描述set key value设置指定key的值为valueget key获取指定key的值del key [key …]删除一个或多个keymset key value [key value …]设置多个key的值mget key [key …]获取一个或多个key的值incr key将key中储存的…

vue项目配置看板娘

这个博主讲的不错&#xff0c;很清楚&#xff0c;但是我实操时无法找到资源&#xff0c;一直报404找不到模型&#xff0c;苦恼了我很久也没解决&#xff0c;之后发现了 Evgo的项目&#xff0c;这就简单多了 最简单的引入Vue看板娘教程 一、项目引入 这里使用的是来自Evgo老哥…

03-JAVA设计模式-工厂模式详解

工厂模式 工厂设计模式是一种创建型设计模式&#xff0c;它提供了一种封装对象创建过程的机制&#xff0c;将对象的创建与使用分离。 这种设计模式允许我们在不修改客户端代码的情况下引入新的对象类型。 在Java中&#xff0c;工厂设计模式主要有三种形式&#xff1a;简单工厂…

每日OJ题_优先级队列_堆③_力扣692. 前K个高频单词

目录 力扣692. 前K个高频单词 解析代码 力扣692. 前K个高频单词 692. 前K个高频单词 难度 中等 给定一个单词列表 words 和一个整数 k &#xff0c;返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率&#xff0c…

潜水后可以戴耳机吗?精选四款防水游泳耳机,不惧水压挑战

随着生活水平的提高&#xff0c;人们越来越注重健康与休闲娱乐。潜水作为一项集运动、探险和乐趣于一身的活动&#xff0c;近年来受到了越来越多的关注。然而&#xff0c;在享受潜水带来的乐趣的同时&#xff0c;我们也希望能够在水下保持与外界的联系&#xff0c;例如欣赏音乐…

经济学 赋税

赋税&#xff1a; 1.为政府服务提供金钱来源 2. 用于保护环境 3.帮助国家使用财政和货币政策&#xff0c;推动经济增长 4.再分配社会财富的一种方式&#xff0c;平衡富人和穷人的贫富差距 5.帮助我们支付市场自身可能无法实现的服务&#xff0c;比如公共安全&#xff0c;国…

【MySQL】解决修改密码时报错:--skip-grant-tables option

首先我们先了解到为何会出现如上报错&#xff1a; 是因为我们在第一次配置MySQL中的my.cnf时&#xff0c;我们添加了–skip–grant-tables 选项 跳过验证身份的选项 所以&#xff0c;我们第一次登录成功后想要修改密码会出现如下报错&#xff1a; [hxiZ0jl69kyvg0h181cozuf5Z…