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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 白羽蘇芳 中级黑马   /  2015-8-26 21:01  /  1685 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

需求:多个窗口卖票。
老毕的课程中,他是这么写的
  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.         }
复制代码
不行么?





13 个回复

倒序浏览
x--在多线程环境下会产生会有线程同步问题,推荐用synchronized代码块修饰
回复 使用道具 举报
其他的都正常,但是我卖出了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--;
                        }
                        
                }
        }
回复 使用道具 举报
多线程还没有涉及到。。。
回复 使用道具 举报
好深奥的说
回复 使用道具 举报
同意2楼的讲解
回复 使用道具 举报
fmi110 高级黑马 2015-8-27 15:52:23
7#
使用     while(true)
                {
                        if (x>0){}
                }
这种形式时,该线程永远不会自动结束,会一直在while循环那里不停的判断循环,while(x>0)时,一旦判断到没票了,对应的售票进程就结束了。
回复 使用道具 举报
好好好好、、、、、
回复 使用道具 举报
pengbeilin 发表于 2015-8-26 22:36
其他的都正常,但是我卖出了103张票。 编号为100的4个线程各卖了一次。。。
这个问题我可以帮你解释下!
p ...

那为啥老毕视频里100的票只卖了一次呢
回复 使用道具 举报
fmi110 发表于 2015-8-27 15:52
使用     while(true)
                {
                        if (x>0){}

没票了就结束呗。。还一直循环做啥咧···
回复 使用道具 举报
白羽蘇芳 发表于 2015-8-27 19:24
没票了就结束呗。。还一直循环做啥咧···

考虑到别人买了 又退票的情况呢  不断的刷票  
回复 使用道具 举报
白羽蘇芳 发表于 2015-8-27 19:23
那为啥老毕视频里100的票只卖了一次呢

其实肯定是会出安全问题的,多个线程操作一个共享数据 又没加同步的话
回复 使用道具 举报
实现了多线程,单没有实现同步问题,没有加锁,看毕向东的多线程的视频吧
回复 使用道具 举报
666666666666666666666666
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马