黑马程序员技术交流社区

标题: 多线程-售票的例子 [打印本页]

作者: 白羽蘇芳    时间: 2015-8-26 21:01
标题: 多线程-售票的例子
需求:多个窗口卖票。
老毕的课程中,他是这么写的
  1. class Ticket extends Thread
  2. {
  3.         private static int x = 100;
  4.         public void run()
  5.         {
  6.                 while(true)
  7.                 {
  8.                         if (x>0)
  9.                         {
  10.                                 System.out.println(Thread.currentThread().getName()+"sale~~~"+x);
  11.                                 x--;
  12.                         }
  13.                         
  14.                 }
  15.         }
  16. }
  17. class TicketDemo
  18. {
  19.         public static void main(String[] args)
  20.         {
  21.                 Ticket t1 = new Ticket();
  22.                 Ticket t2 = new Ticket();
  23.                 Ticket t3 = new Ticket();
  24.                 Ticket t4 = new Ticket();
  25.                 t1.start();
  26.                 t2.start();
  27.                 t3.start();
  28.                 t4.start();
  29.         }
  30. }
复制代码
视频里,他运行没问题,因为票会卖重复,所以给100张票加上静态了。
但是我一运行, ,其他的都正常,但是我卖出了103张票。 编号为100的4个线程各卖了一次。。。
这问题怎么解决?为啥运行起来会不同
PS:还有个问题,视频中是
  1. public void run()
  2.         {
  3.                 while(true)
  4.                 {
  5.                         if (x>0)
  6.                         {
  7.                                 System.out.println(Thread.currentThread().getName()+"sale~~~"+x);
  8.                                 x--;
  9.                         }
  10.                         
  11.                 }
  12.         }
复制代码
我不明白这个while和if为什么要这么用
直接
  1. public void run()
  2.         {
  3.                 while(x>0)
  4.                 {
  5.                         
  6.                         System.out.println(Thread.currentThread().getName()+"sale~~~"+x);
  7.                         x--;
  8.                 }
  9.         }
复制代码
不行么?






作者: 哈皮哈皮doge    时间: 2015-8-26 22:06
x--在多线程环境下会产生会有线程同步问题,推荐用synchronized代码块修饰
作者: pengbeilin    时间: 2015-8-26 22:36
其他的都正常,但是我卖出了103张票。 编号为100的4个线程各卖了一次。。。
这个问题我可以帮你解释下!
public void run()
        {
                while(true)
                {
                        if (x>0)
                        {
//运行之后 第0个线程判断之后 x=100 挂在这里(有执行权,无执行资格),
//然后第1个线程抢到了执行权也进来了,判断之后x还是=100,然后又被挂在这里(有执行权,无执行资格)
//同样的第2个线程,第3个线程都可能会出现同样的情况,~
//最后0号线程抢到执行权 输出100号票,1号线程抢到执行权也是输出100号票~ 同样的2号3号也输出了100号票
                                System.out.println(Thread.currentThread().getName()+"sale~~~"+x);
                                x--;
                        }
                        
                }
        }
作者: code_linux    时间: 2015-8-26 22:44
多线程还没有涉及到。。。
作者: 13706649811    时间: 2015-8-26 22:55
好深奥的说
作者: 三分之一    时间: 2015-8-27 14:28
同意2楼的讲解
作者: fmi110    时间: 2015-8-27 15:52
使用     while(true)
                {
                        if (x>0){}
                }
这种形式时,该线程永远不会自动结束,会一直在while循环那里不停的判断循环,while(x>0)时,一旦判断到没票了,对应的售票进程就结束了。

作者: MoonsenHung    时间: 2015-8-27 16:07
好好好好、、、、、
作者: 白羽蘇芳    时间: 2015-8-27 19:23
pengbeilin 发表于 2015-8-26 22:36
其他的都正常,但是我卖出了103张票。 编号为100的4个线程各卖了一次。。。
这个问题我可以帮你解释下!
p ...

那为啥老毕视频里100的票只卖了一次呢
作者: 白羽蘇芳    时间: 2015-8-27 19:24
fmi110 发表于 2015-8-27 15:52
使用     while(true)
                {
                        if (x>0){}

没票了就结束呗。。还一直循环做啥咧···
作者: fmi110    时间: 2015-8-27 20:51
白羽蘇芳 发表于 2015-8-27 19:24
没票了就结束呗。。还一直循环做啥咧···

考虑到别人买了 又退票的情况呢  不断的刷票  
作者: pengbeilin    时间: 2015-8-27 22:17
白羽蘇芳 发表于 2015-8-27 19:23
那为啥老毕视频里100的票只卖了一次呢

其实肯定是会出安全问题的,多个线程操作一个共享数据 又没加同步的话
作者: forjunjian    时间: 2015-8-27 22:56
实现了多线程,单没有实现同步问题,没有加锁,看毕向东的多线程的视频吧
作者: jaunce    时间: 2015-8-27 22:58
666666666666666666666666




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