A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 睡不够的猪 中级黑马   /  2013-10-23 11:54  /  1235 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. class SaleTicketTest
  2. {
  3. public static void main(String[] args)
  4. {
  5. SaleTicket t =new SaleTicket();
  6. new Thread(t).start();
  7. new Thread(t).start();
  8. new Thread(t).start();
  9. new Thread(t).start();
  10. }
  11. }


  12. class SaleTicket implements Runnable
  13. {
  14. private int ticket=100;

  15. public void run()
  16. {

  17. while(ticket>0)
  18. {
  19. /*
  20. 假如线程0、1、2、3都进来了
  21. 然后0线程执行了 然后1、2、3都执行
  22. 结果会出现负数 说明1、2、3执行后打印的ticket是ticket--之后的数据

  23. 那为什么会出现小数据打印后还会打印大数据的现象呢???

  24. ----->比如 0线程打印了63 出现1线程打印64是什么原因?
  25. */
  26. try
  27. {
  28. Thread.sleep(10);
  29. }
  30. catch (Exception e)
  31. {
  32. }
  33. System.out.println(Thread.currentThread().getName()+"run...:"+ticket--);


  34. }

  35. }
  36. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
To + 1

查看全部评分

3 个回复

倒序浏览
本帖最后由 周学彬 于 2013-10-23 12:13 编辑

由于是多线程并发执行,所以每个线程会抢占所有的系统资源,包括输出设备——控制台。所以,当某个线程执行了run()方法,即将打印时,却被另一个线程抢先执行run()方法,并抢占了输出控制台资源,那么就会执行后一个线程,即打印较小的票了。
至于为什么打印负数,那时因为该段代码的多线程实现并不安全,因为操作共享数据而没有同步锁,你看到后面的视频就会明白了。最简单的办法就是给run()方法添加一个同步声明,使用synchronized语句,这样就不会打印负数了
代码实现如下:
  1. class ThreadTest
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 SaleTicket t =new SaleTicket();
  6.                 new Thread(t).start();
  7.                 new Thread(t).start();
  8.                 new Thread(t).start();
  9.                 new Thread(t).start();
  10.         }
  11. }


  12. class SaleTicket implements Runnable
  13. {
  14.         private int ticket=100;
  15.         
  16.         public void run()
  17.         {
  18.                 synchronized(this) {
  19.                 while(ticket>0)
  20.                 {
  21.                         /*
  22.                         假如线程0、1、2、3都进来了
  23.                         然后0线程执行了 然后1、2、3都执行
  24.                         结果会出现负数 说明1、2、3执行后打印的ticket是ticket--之后的数据
  25.                         
  26.                         那为什么会出现小数据打印后还会打印大数据的现象呢???
  27.                         
  28.                         ----->比如 0线程打印了63 出现1线程打印64是什么原因?
  29.                         */
  30.                         
  31.                         try
  32.                         {
  33.                                 Thread.sleep(10);
  34.                         }
  35.                         catch (Exception e) {}
  36.                                 System.out.println(Thread.currentThread().getName()+"run...:"+ticket--);
  37.                         }
  38.                 }
  39.         
  40.         }
  41. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
周志龙 + 1 很给力!

查看全部评分

回复 使用道具 举报
周学彬 发表于 2013-10-23 12:11
由于是多线程并发执行,所以每个线程会抢占所有的系统资源,包括输出设备——控制台。所以,当某个线程执行 ...

我知道是线程抢夺cpu执行权的问题 按照你说的 会出现多个线程卖出同一个票号的现象 但是还是想不明白为什么会先出现小号 再出现大号的现象

另外你把锁加在循环外面的话 结果是某一个线程会把票都卖完的!
回复 使用道具 举报
楼主你好,如果问题已解决请将帖子状态修改为提问结束,

如果未解决请继续提问,谢谢合作

修改方法请看解释帖:http://bbs.itheima.com/thread-89313-1-1.html
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马