• 那是从何处传来的钟声呢?偶尔听到那钟声,平添一份喜悦与向往之情。

Java多线程卖火车票例子出现负数票

后端 Nanait 11年前 (2012-12-18) 1153次浏览 已收录 0个评论 扫描二维码

有个小伙伴提了个Java多线程卖票的例子,问为什么出现负数票。试着在电脑上运行了一下,最终得出答案,这里做个笔记,也希望对大家有益。

假设原题

  1. public class TicketThread implements Runnable {
  2.     static int tickets = 100;// 火车票数量
  3.     @Override
  4.     public void run() {
  5.         // 出售火车票
  6.         while (tickets>0) {
  7.             method();
  8.         }
  9.     }
  10.      private  void method() {
  11.         if (tickets > 0) {
  12.             try {
  13.                 /*
  14.                  *  1.为什么会出现负数票
  15.                  *  2.分析
  16.                  *  (1)当票数等于 1 的时候 可能有 2 个线程判断完 if 语句但是,还在休眠
  17.                  *  (2)休眠结束后  继续执行卖票环节
  18.                  *  (3)出现负数票
  19.                  */
  20.                 Thread.sleep(10);
  21.             } catch (InterruptedException e) {
  22.                 e.printStackTrace();
  23.             }
  24.             System.out.println(Thread.currentThread().getName() + “:” + tickets–);
  25.         }
  26.     }
  27.     public static void main(String[] args) {
  28.         TicketThread ticketThread = new TicketThread();
  29.         Thread t1 = new Thread(ticketThread,“甲站台”);
  30.         Thread t2 = new Thread(ticketThread,“乙站台”);
  31.         Thread t3 = new Thread(ticketThread,“丙站台”);
  32.         Thread t4 = new Thread(ticketThread,“丁站台”);
  33.         t1.start();
  34.         t2.start();
  35.         t3.start();
  36.         t4.start();
  37.     }
  38. }

运行后,可能会出现 负数票,如下

Java 多线程卖火车票例子出现负数票

 

分析:为什么会如此。我们可以假设,当只有一张票的时候,乙,甲、丙和丁四个线程依次加入就绪队列,乙线程先获得 CPU 执行权,通过 if 语句,然后在 sleep(10)下休眠(注意,就是这个地方),也就是在这短时间,加、丙和丁线程也依次通过了 if 语句。10 ms 后,乙线程 执行下面的打印票信息,即 1 号票,然后,另外三个线程也依次苏醒,输出 0 号票,-1 号票,-2 号票。

 

解决方案:让 “打印票信息和 tickets–”在 sleep(10) 前面 输出,不给其他线程“趁机”溜进来的机会。当然,我们这里的 sleep 休眠的时间不能设置太短,10ms 以上为好,如果是 1ms 就不太好。

 


何处钟 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Java 多线程卖火车票例子出现负数票
喜欢 (0)
[15211539367@163.com]
分享 (0)

您必须 登录 才能发表评论!