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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 zq19910303 于 2015-5-19 06:38 编辑

为什么这个卖票代码每次运行都会出现四个100-----------问这个问题的目的是为了分析代码错在了哪里,为什么会错
  1. /*需求:四个窗口卖100张票*/
  2. class Ticket extends Thread
  3. {
  4.         
  5.         private static int t=100;
  6.         public void run()
  7.         {
  8.                 while (t>0)
  9.                 {
  10.                         System.out.println(Thread.currentThread().getName()+"----------sale:"+t);
  11.                         t--;
  12.                 }
  13.         }
  14. }

  15. class TicketDemo
  16. {
  17.         public static void main(String[] args)
  18.         {
  19.                 Ticket t1=new Ticket();
  20.                 Ticket t2=new Ticket();
  21.                 Ticket t3=new Ticket();
  22.                 Ticket t4=new Ticket();
  23.                 t1.start();
  24.                 t2.start();
  25.                 t3.start();
  26.                 t4.start();

  27.         }
  28. }
复制代码

这是因为第十行和第十一行代码的原因,与cpu核心数量无关,如果cpu在执行完t1的第十行后就去执行t2了,那么就会出现两个一百了,同理就能分析出四个一百的原因,而且其他的数字也有可能出现多次,这是代码的不严谨导致的。将十与十一合并后就会解决这个问题。当合并后出现两次相同的数字,那就是因为cpu是双核的原因了。

14 个回复

倒序浏览
这个因为你没有进行同步,几个线程可以同时调用资源,但也不一定出现 四次100
回复 使用道具 举报
mmakun 发表于 2015-5-18 14:24
这个因为你没有进行同步,几个线程可以同时调用资源,但也不一定出现 四次100 ...

是每次都会出现四个100,同步只能解决出现0  -1  -2的情况
回复 使用道具 举报
老夫帮你改了一下
   System.out.println(Thread.currentThread().getName()+"----------sale:"+t--);
输出语句改成这个就行了  你的t--有点慢你都知道是多线程了   我语言表达能力不太好,我也不是很会解释  多线程就是 卡在t--之前就运行了 你的那个代码我试了一下不是每次都是4个100...不过基本上都是2个以上100~~~
回复 使用道具 举报
语言表达不通顺  你原谅我吧 凑合着看就好了  哇咔咔    ~~你的每次都是1个400个100的话只能得出一个结论,那就是  你的电脑是4核的吧 我的是双核 所以至少2个100 ........ 都是一起运行的,执行到第一局的时候  4个线程都指向到了第一局的输出 都输出之后   t--
我整理了一下~~~
回复 使用道具 举报
你要将票设置为单例设计模式思想
回复 使用道具 举报
志行 发表于 2015-5-18 15:40
语言表达不通顺  你原谅我吧 凑合着看就好了  哇咔咔    ~~你的每次都是1个400个100的话只能得出一个结论, ...

你好,我的cpu是双核的。至于出现四个100的情况,经过你的提醒我想明白了。这是因为第十行和第十一行代码的原因,与核心数量无关,如果cpu在执行完t1的第十行后就去执行t2了,那么就会出现两个一百了,同理就能分析出四个一百的原因,而且其他的数字也有可能出现多次,这是代码的不严谨导致的。将十与十一合并后就会解决这个问题。当合并后出现两次相同的数字,那就是因为cpu是双核的原因了。
回复 使用道具 举报
jiangwenjun 发表于 2015-5-18 17:17
你要将票设置为单例设计模式思想

正确方法我已知道了,我想在想知道的是这个代码错误的原因
回复 使用道具 举报
学习中
回复 使用道具 举报
zq19910303 发表于 2015-5-18 14:48
是每次都会出现四个100,同步只能解决出现0  -1  -2的情况

那你得多运行几下
回复 使用道具 举报
在多线程处理共享数据时不加锁,很容易出现安全隐患,就算你把10 11行合并,还是会出现两个100甚至更多的100
回复 使用道具 举报
rose_xiaomei 发表于 2015-5-18 18:43
在多线程处理共享数据时不加锁,很容易出现安全隐患,就算你把10 11行合并,还是会出现两个100甚至更多的10 ...

是的,但我设置这个问题的初衷是为了分析不加锁时为什么会有这种安全问题:)
回复 使用道具 举报
本帖最后由 大西洋 于 2015-5-18 21:39 编辑

怎么可能因为双核。。。。我的CPU六核也没出现4个100,你的代码少了很多东西;我是这样写的:
  1. class Ticket extends Thread{
  2.         private static int tk = 100;
  3.         Object obj = new Object();
  4.         public void run() {
  5.                 while (true) {
  6.                         synchronized (obj) {                               
  7.                                 if (tk > 0) { // 只要有票就继续
  8.                                         System.out.println(Thread.currentThread().getName()+"........sale:  " + tk--);
  9.                                         try {
  10.                                                 Thread.sleep(300); // 因为CPU执行速度太快,所以让每个线程睡一会儿可以看清过程
  11.                                         } catch (InterruptedException e) {
  12.                                                 e.printStackTrace();
  13.                                         }
  14.                                 }else {// 没票就退出循环,否则javaw.exe进程会一直占用CPU资源。。。
  15.                                         break;
  16.                                 }
  17.                         }
  18.                 }
  19.         }
  20. }

  21. public class TestTicket {

  22.         public static void main(String[] args) {
  23.                 // 实例化线程
  24.                 Ticket t1 = new Ticket();
  25.                 Ticket t2 = new Ticket();
  26.                 Ticket t3 = new Ticket();
  27.                 Ticket t4 = new Ticket();
  28.                 // 启动线程
  29.                 t1.start();
  30.                 t2.start();
  31.                 t3.start();
  32.                 t4.start();
  33.                
  34.         }
  35. }
复制代码



运行结果:
  1. Thread-0........sale:  100
  2. Thread-2........sale:  98
  3. Thread-1........sale:  99
  4. Thread-3........sale:  97
  5. Thread-3........sale:  96
  6. Thread-1........sale:  93
  7. Thread-0........sale:  95
  8. Thread-2........sale:  94
  9. Thread-1........sale:  92
  10. Thread-0........sale:  91
  11. Thread-3........sale:  89
  12. Thread-2........sale:  90
  13. Thread-2........sale:  88
  14. Thread-0........sale:  88
  15. Thread-1........sale:  88
  16. Thread-3........sale:  87
  17. Thread-3........sale:  85
  18. Thread-1........sale:  83
  19. Thread-2........sale:  86
  20. Thread-0........sale:  84
  21. Thread-3........sale:  82
  22. Thread-0........sale:  81
  23. Thread-2........sale:  80
  24. Thread-1........sale:  82
  25. Thread-2........sale:  79
  26. Thread-3........sale:  76
  27. Thread-1........sale:  78
  28. Thread-0........sale:  77
  29. Thread-0........sale:  75
  30. Thread-1........sale:  74
  31. Thread-3........sale:  74
  32. Thread-2........sale:  73
  33. Thread-3........sale:  72
  34. Thread-2........sale:  71
  35. Thread-1........sale:  72
  36. Thread-0........sale:  71
  37. Thread-3........sale:  71
  38. Thread-2........sale:  68
  39. Thread-0........sale:  70
  40. Thread-1........sale:  69
  41. Thread-1........sale:  66
  42. Thread-3........sale:  66
  43. Thread-0........sale:  67
  44. Thread-2........sale:  65
  45. Thread-3........sale:  64
  46. Thread-2........sale:  63
  47. Thread-1........sale:  62
  48. Thread-0........sale:  64
  49. Thread-2........sale:  61
  50. Thread-3........sale:  61
  51. Thread-0........sale:  60
  52. Thread-1........sale:  59
  53. Thread-3........sale:  58
  54. Thread-1........sale:  55
  55. Thread-2........sale:  57
  56. Thread-0........sale:  56
  57. Thread-0........sale:  53
  58. Thread-3........sale:  54
  59. Thread-2........sale:  54
  60. Thread-1........sale:  53
  61. Thread-3........sale:  51
  62. Thread-1........sale:  52
  63. Thread-0........sale:  50
  64. Thread-2........sale:  49
  65. Thread-3........sale:  48
  66. Thread-0........sale:  45
  67. Thread-2........sale:  47
  68. Thread-1........sale:  46
  69. Thread-0........sale:  44
  70. Thread-1........sale:  43
  71. Thread-2........sale:  42
  72. Thread-3........sale:  41
  73. Thread-3........sale:  38
  74. Thread-2........sale:  40
  75. Thread-1........sale:  39
  76. Thread-0........sale:  40
  77. Thread-2........sale:  36
  78. Thread-1........sale:  34
  79. Thread-0........sale:  35
  80. Thread-3........sale:  37
  81. Thread-1........sale:  33
  82. Thread-3........sale:  33
  83. Thread-2........sale:  33
  84. Thread-0........sale:  32
  85. Thread-3........sale:  31
  86. Thread-2........sale:  29
  87. Thread-0........sale:  30
  88. Thread-1........sale:  30
  89. Thread-0........sale:  28
  90. Thread-1........sale:  27
  91. Thread-2........sale:  28
  92. Thread-3........sale:  26
  93. Thread-0........sale:  25
  94. Thread-2........sale:  22
  95. Thread-1........sale:  23
  96. Thread-3........sale:  24
  97. Thread-2........sale:  20
  98. Thread-0........sale:  21
  99. Thread-3........sale:  21
  100. Thread-1........sale:  19
  101. Thread-3........sale:  18
  102. Thread-1........sale:  16
  103. Thread-2........sale:  17
  104. Thread-0........sale:  15
  105. Thread-3........sale:  14
  106. Thread-1........sale:  12
  107. Thread-0........sale:  14
  108. Thread-2........sale:  13
  109. Thread-3........sale:  11
  110. Thread-0........sale:  8
  111. Thread-1........sale:  9
  112. Thread-2........sale:  10
  113. Thread-2........sale:  7
  114. Thread-3........sale:  7
  115. Thread-0........sale:  5
  116. Thread-1........sale:  6
  117. Thread-1........sale:  4
  118. Thread-2........sale:  2
  119. Thread-3........sale:  3
  120. Thread-0........sale:  1
复制代码





回复 使用道具 举报
用runnable就好了
回复 使用道具 举报
懒儿想想 来自手机 中级黑马 2015-5-18 23:09:14
15#
没看明白
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马