首页 > 其他分享 >关于线程问题的探讨(售票问题)

关于线程问题的探讨(售票问题)

时间:2023-07-14 22:56:30浏览次数:53  
标签:售票 语句 问题 休眠 线程 ticketNum

package SellTickets;

public class SellTickets01 implements Runnable{

    private static int ticketNum = 100;

    @Override
    public void run() {
        while(true)
        {
            if(ticketNum<=0)
            {
                System.out.println("售票结束...");
                break;
            }
            try{
                Thread.sleep(50);
            }catch (Exception e)
            {
                throw new RuntimeException(e);
            }
            
            System.out.println("窗口"+Thread.currentThread().getName()+"剩余票数:"+(--ticketNum));
        }
    }

    public static void main(String[] args) {
        SellTickets01 sellTickets01 = new SellTickets01();
        SellTickets01 sellTickets02 = new SellTickets01();
        SellTickets01 sellTickets03 = new SellTickets01();
        Thread thread01 = new Thread(sellTickets01);
        Thread thread02 = new Thread(sellTickets02);
        Thread thread03 = new Thread(sellTickets03);
        thread01.start();
        thread02.start();
        thread03.start();
    }
}    

首先这是韩顺平老师的售票代码,老师发现了超售的问题(剩余票数小于0了,截图如下)

 那么面对这样的问题我们该怎么解决呢?

我是这样分析的,首先这段代码有一段50毫秒的休眠Thread.sleep(50),那么在这一线程休眠的时候,其他没有休眠的线程肯定会运行。那么好了,此时假设我们的01线程已经进入了休眠,那它必定已经走过了if(ticketNum<=0)语句,休眠结束以后它必定会执行System.out.println("窗口"+Thread.currentThread().getName()+"剩余票数:"+(--ticketNum));语句,那么也就意味着票数必定会减一。那么好,如果01线程进入休眠前if语句判断的ticketNum正好等于1,按我们的思维逻辑票肯定不能再卖了,但是其他的线程并不这么认为,因为在01线程休眠时,假设02线程执行if(ticketNum<=0)语句,而此时ticketNum还是等于1,所以它也不会跳出while循环,并将继续执行下面的语句,进入休眠,休眠结束以后执行System.out.println("窗口"+Thread.currentThread().getName()+"剩余票数:"+(--ticketNum));语句,那么我们的ticketNum就执行两次减一,票数变成-1,不符合实际情况。

我描述的有点繁琐,但是基本意思我想已经表达清楚了。改进方法也很简单,因为我们的if语句在线程休眠之前才导致了问题的产生,那么把if语句放在程序休眠之后就不会出现类似的问题了。

 我试了好几次都是这个结果,所以我想大概率问题解决了,如果有什么考虑欠缺的地方,非常欢迎给位大佬为我提出来,谢谢!

另外还有一个方法,只要让--ticketNum这个语句提前,执行完if语句后立马令ticketNum减一,那么线程就可以放心的休眠了。

 只是想了好久,弄不明白为什么会有这么多剩余票为0输出。

标签:售票,语句,问题,休眠,线程,ticketNum
From: https://www.cnblogs.com/nashacjj/p/17554823.html

相关文章

  • 修复域名访问问题
    研究了一下午,一开始思考为什么不能一直用域名访问,在主页面点进新页面后就不能继续使用域名访问了,所以就开始修复这个问题,问了问AI是反向代理服务器的问题,结果给我网站搞崩了,查了一堆资料还是没解决,结果自己随便逛了逛宝塔面板,看到PHP是静态的,我就知道问题了,妈的,还是自己的脑袋聪......
  • 配置问题-Error creating bean with name 'user' defined in class path resource [be
    正在学习IoC使用的jdk版本为jdk17依赖为:<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>6.0.6</version></dependen......
  • shell多线程/实例
    1.Shell实现多进程  使用&和wait配合实现shell多进程并行  参考连接:https://blog.csdn.net/yuefei169/article/details/83340480  (1)改串行执行为并行执行方式:将前台执行命令放在后台执行(串行命令后加&符号).(生产少使用该方式)  (2)使用元祖模拟队列来控制进程数......
  • SQL注入问题、视图、触发器、事务、存储过程、函数、流程控制、索引、测试索引
    SQL注入问题连接MySQL服务器conn=pymysql.connect(host=‘127.0.0.1’port=3306user=‘root’password='1234'......
  • 了不起的魔术师问题
    目录了不起的魔术师问题前言问题描述解决方案参考了不起的魔术师问题前言此问题来自于<<Python编程:从入门到实践>>第一版中习题8-10.问题描述了不起的魔术师:创建一个包含魔术师名字的列表,并将其传递给一个名为show_magicians()的函数,这个函数打印列表中每个魔术......
  • Qt信号槽信号函数重载问题 error: C2664: “QMetaObject::Connection const”
    //connect(spinFontSize,&QSpinBox::valueChanged,this,&MainWindow::spinFontSize_valueChanged);//由于信号函数存在重载,发送者找不到正确信号函数。//改用A.Qt4带形参方式//connect(spinFontSize,SIGNAL(valueChanged(int)),this,SLOT(spinFontSize_valueChang......
  • vue进行页面跳转样式丢失问题
    问题:vue使用 this.$router.push方法进行页面跳转时样式丢失,如下图,图一为正常页面,图二为跳转后的界面  解决方法:并非样式丢失,而是样式背覆盖了,去跳转的原界面样式中加入scope,跳转之后问题解决 ......
  • 自定义图标偏移问题
    在地图开发中使用自定义图标(icon)在地图上表达专题信息十分常见leaflet中常使用L.marker添加图标L.icon,非常方便给定坐标将图标固定在地图中的某个位置,由于图标是有具体大小,并且大小固定不变,在缩放过程中有明显感觉随着地图比例尺缩小,图标会有一定的偏移这篇文章主要介绍使用L......
  • ABA问题
    ABA问题是并发编程中的一个经典问题,主要涉及多线程和共享变量的操作。在多线程环境中,如果多个线程对同一个共享变量进行读取和修改操作,可能会导致ABA问题。ABA问题指的是以下情况:线程A读取共享变量的值为A。线程A被调度出去,线程B进入执行,并将共享变量的值修改为B。线程B被调......
  • 关于.properties文件使用中文出现乱码问题,及在eclipse和idea中如何查看
    最近修改一个老java项目(使用jdk1.6),发现在eclipse中打开.properties文件,有中文字符的都变成了类似 \u901a\这样的字符,查看文件编码已经是UTF-8,即使用idea打开也是如此,而且idea文件编码是灰色,无法修改;搜索了一番,终于找到了相应的查看方法,其实就是编辑器给你再转回汉字......