1.卖票案例需求分析

某天某个景区售票,门票票只有100张,景区有三个售票窗口,同时售票,共享票源(100张)
通过多线程的方式实现三个售票窗口同时售票

  1. 首先要明确票源只能有一个
  2. 其次需要创建三个Thread的对象去执行卖票的方法,卖完票后要将剩余的票数返回给统一的票源;

2.代码实现

1.票源和多线程执行入口代码

public class Ticket implements Runnable {private int tickets = 100;  //票源TicketOffice ticketOffice = new TicketOffice();@Overridepublic void run() {while(true){this.tickets = ticketOffice.sellTicket(tickets);  //sellTicket由synchronized修饰//返回的tickets重新传给成员变量this.tickets以保证票源的一致}}
}

2.售票规则代码

public class TicketOffice {public synchronized int sellTicket(int tickets) {if (tickets > 0) {try {Thread.sleep(0);  //模拟CPU忙碌的停顿} catch (InterruptedException e) {e.printStackTrace();}Thread th = Thread.currentThread();System.out.println(th.getName() + " 线程数为:" + Thread.activeCount() + "  出售第:" + tickets--);}return tickets;}
}

在案例中我把售票窗口代码写道了另一个类中,并设置为了静态方法,可以直接通过类名来调用
3.测试类代码

public class ThreadDemo {public static void main(String[] args) {Ticket ticket = new Ticket();  //票源固定100张Thread thread0 = new Thread(ticket);  //创建新线程thread0.start();Thread thread1 = new Thread(ticket);thread1.start();Thread thread2 = new Thread(ticket);thread2.start();}
2.1 结果分析

为了分析结果的方便,我们将票源修改为5张,观察结果是否出错

!!! 显然输出结果有问题,我们设置的票源总共有5张,而此时三个窗口总和加起来卖了15张!

2.2 问题分析

通过代码分析发现是synchronized锁的不够全面出现的,在售票规则代码块中售票方法被synchronized修饰,方法内部的共享数据tickets被锁住,一个线程为执行完方法时,另一线程不允许进入。==方法内部的“门”锁好了,但是忽略的run()中调用方法需要传形参的这道“门”!==由于ticketOffice.sellTicket(tickets);方法运行时间较长,在传入形参的时候有可能三个线程都进行了ticketOffice.sellTicket(tickets);中形参的赋值任务,从而导致会输出三个线程都从第5张票开始贩卖。因此我们需要在外部也就是this.tickets = ticketOffice.sellTicket(tickets);的外部也加上synchronized代码块,从而使得共享成员不会错误赋值。

3.代码修改

只需要在外部也就是this.tickets = ticketOffice.sellTicket(tickets);的外部也加上synchronized代码块即可;

public class Ticket implements Runnable {private int tickets = 100;TicketOffice ticketOffice = new TicketOffice();@Overridepublic void run() {while(true){synchronized (this) {this.tickets = ticketOffice.sellTicket(tickets);  //sellTicket由synchronized修饰}}}
}

这样运行出的结果就是正确的了

小结:大家在其他地方应该也看到过类似的案例,他们一般是把售票规则代码与run()方法放在同一个类中,这样会避免许多错误,这样就显得我的改动可能是画蛇添足,不过还是能从这样的修改中明白synchronized的使用位置,和文章中这种错误出现的原因所在;所以个人认为代码不能按着老师的写法来,学习代码我们需要有自己的思路,自己的方法,遇到问题需要用自己解决问题的方式。

问题:在运行过程中我发现,在没有synchronized修饰线程操作所共享数据时,输出结果中每个线程都有售出票的显示,而加入synchronized操作时结果显示虽然有3个(输出中显示5个,是因为包含了main和JVM虚拟机运行所使用的线程)线程在运行,但只有Thread-0在售票,很疑惑…

Java多线程(卖票案例)相关推荐

  1. java 多线程 卖票_编写一个Java 多线程程序,完成三个售票窗口同时出售20张票(如下图所示);...

    编写一个Java 多线程程序,完成三个售票窗口同时出售20张票(如下图所示); 程序分析:(1)票数要使用同一个静态值: (2)为保证不会出现卖出同一个票数,要java多线程同步锁. 设计思路: (1 ...

  2. Java 多线程 卖票

    需求: 某电影院目前正在上映国产大片, 公有100张票 , 而它有3个窗口卖票, 设计一个程序模拟该电影院卖票 1.定义一个类SellTicke实现Runnable接口, 里面定义一个成员变量: 2. ...

  3. 卖票案例 多线程 java 1615387415

    卖票案例 多线程 java 1615387415 解决 线程类 测试类 注意,需要给线程的类添加带参构造方法 在带参构造方法中 调一下父类的带参构造方法 最终结果 每个窗口都卖了一百张票

  4. java多线程,卖票案例

    目录 卖票案例 测试代码 代码1 代码2,卖票问题的思考 代码3 代码4 代码5 卖票案例 测试代码 package com.itheima_06;/*需求:某电影院目前正在上映国产大片,共有100张 ...

  5. 多线程:线程同步与死锁(卖票案例)、线程通信、生产者与消费者

    卖票案例 5个窗口同时卖票: 使用Runnable接口,只创建了一个ticket1对象,5个线程共享此对象,实现了资源共享. public class ticket1 implements Runna ...

  6. Java代码实现多线程卖票

    写一个多线程卖票的程序 /*** @author tom* @date 2022-03-29 15:33*/ public class SaleTickets {public static void ...

  7. Lock锁实现多线程卖票

    理解多线程卖票demo Lock架构 使用lock替代synchronized 总结 使用Lock 实现. Lock架构 使用lock替代synchronized import java.util.c ...

  8. JUC学习(二):Lock的介绍及使用(实现多线程卖票)

    一.Lock简介 Lock 锁实现提供了比使用同步方法和语句可以获得的更广泛的锁操作.它们允许更灵活的结构,可能具有非常不同的属性,并且可能支持多个关联的条件对象.Lock 提供了比 synchron ...

  9. Python 多线程卖票问题

    Python 多线程卖票问题 在学习多线程的时候,我们经常要学习到多窗口售票这一经典案例,今天我们将用Python语言写一个简单易懂的售票程序,帮助大家学习理解 有以下要求: 第一.不能出现打印出现混 ...

最新文章

  1. 【js】内置对象String的常用方法
  2. IMLS:用于3D重构的深层隐式移动最小二乘函数(CVPR2021)
  3. How Tomcat Works(十一)
  4. 并发队列-无界阻塞优先级队列
  5. R12.1.3 R12.2.X 注册客户化应用
  6. 谈谈跨界在软件开发中存在的意义
  7. MongoDB索引策略和索引类型
  8. Javascript引擎单线程机制及setTimeout执行原理说明
  9. Qt:Qt实现网页自动刷新工具
  10. 打开windows批处理大门
  11. Selenium自动化测试-文件上传
  12. php网站开发实例教程源码,PHP+MYSQL网站开发全程实例
  13. 18位华人当选2022年加拿大工程院院士!京东副总裁梅涛入选!
  14. 教学|zbrush雕刻头发笔刷介绍,巧用工具可以事半功倍哦!
  15. opencv+映美相机,从缓冲区中抓图片或者显示视频
  16. weak和alias
  17. skb_buff结构体解析
  18. matlab绘制圆极化波,圆极化波及其MATLAB仿真_西电
  19. java生成树形Excel_poi从excel中读取父子关系型(树形)数据结构到数据库
  20. 《VS如何解决Cannot find or open the PDB file问题》

热门文章

  1. LAMP环境搭建与配置(一)
  2. autodesk系列产品无法安装解决方案
  3. 【车间调度】车间调度问题的特点
  4. DSP_TMS320F2802x_CMPSS逐波限流功能实现
  5. Largest Rectangle in a Histogram HDU - 1506 解题思路 单调栈
  6. leetcode:前 K 个高频元素、删除字符串中的所有相邻重复项、有多少小于当前数字的数字、有效的山脉数组、独一无二的出现次数(JavaScript)
  7. 中文用户输入纠错 综述
  8. 阿里云服务器安装mysql数据库教程
  9. render()到底渲染的什么?
  10. mysql的group语句_MySQL中distinct与group by语句的一些比较及用法讲解