黑马程序员技术交流社区

标题: 为什么这个卖票代码会产生四个100 [打印本页]

作者: zq19910303    时间: 2015-5-18 14:17
标题: 为什么这个卖票代码会产生四个100
本帖最后由 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是双核的原因了。

作者: mmakun    时间: 2015-5-18 14:24
这个因为你没有进行同步,几个线程可以同时调用资源,但也不一定出现 四次100
作者: zq19910303    时间: 2015-5-18 14:48
mmakun 发表于 2015-5-18 14:24
这个因为你没有进行同步,几个线程可以同时调用资源,但也不一定出现 四次100 ...

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

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

正确方法我已知道了,我想在想知道的是这个代码错误的原因
作者: Always,    时间: 2015-5-18 17:40
学习中
作者: mmakun    时间: 2015-5-18 18:18
zq19910303 发表于 2015-5-18 14:48
是每次都会出现四个100,同步只能解决出现0  -1  -2的情况

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

是的,但我设置这个问题的初衷是为了分析不加锁时为什么会有这种安全问题:)
作者: 大西洋    时间: 2015-5-18 20:52
本帖最后由 大西洋 于 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
复制代码






作者: 诺诺    时间: 2015-5-18 20:56
用runnable就好了
作者: 懒儿想想    时间: 2015-5-18 23:09
没看明白




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2