黑马程序员技术交流社区

标题: 多线程卖票的例子,用for循环打印结果出问题了 [打印本页]

作者: 郭冰川    时间: 2012-12-31 20:04
标题: 多线程卖票的例子,用for循环打印结果出问题了
本帖最后由 郭冰川 于 2013-1-1 16:44 编辑

class Ticket extends Thread
{
        static int x;
        public void run()
        {
                for (x = 100;x>0 ;x-- )
                {
                        System.out.println(this.getName()+"sale....."+x);
                }
               
        }
}

class  TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t1 = new Ticket();
                Ticket t2 = new Ticket();
                Ticket t3 = new Ticket();
                Ticket t4 = new Ticket();
                t4.start();
                t1.start();
                t2.start();
                t3.start();
               
        }
}

打印结果:
先出现了四个重复的100,然后下面的就都不重复了,四个100是咋回事呢?

作者: 马志军    时间: 2012-12-31 20:14
本帖最后由 马志军 于 2012-12-31 20:18 编辑

没有同步
多个线程执行共享数据,一个线程可能对多条语句执行了一部分,另一个线程又执行部分,就会发生安全问题。
比如线程3,遇到for,x初始赋为100,还没输出呢,线程0抢到执行权,又for,x为100,然后线程3执行了输出100,线程0因为开始已经走过for里面了,x是100,所以它也输出100
作者: cyh8807    时间: 2012-12-31 20:46
多线程运行中的安全问题:
问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完
另一个线程参与进来执行,导致共享数据的错误。
   解决办法:对多条操作共享数据的语句,只能让一个线程执行完毕,在执行过程中,其他线程不可以参与执行。
    可以只用synchronized 方法或者代码块来出来,也可以使用 lock 来解决这样的问题
建议你多往后面学习,前面遇到的这些问题就迎刃而解了
作者: 郭冰川    时间: 2012-12-31 20:53
赵彦辉 发表于 2012-12-31 20:46
多线程运行中的安全问题:
问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行 ...

我试过加同步代码块,结果一样,而且for循环那只有一个语句不会被分开读,也就不存在代码安全问题,还有就是如果是因为代码安全问题的话,为什么只有100重复,后面的却不出现重复的情况呢
作者: 程宏志    时间: 2012-12-31 21:11
你多运行几次,还会有不同的结果。需要同步的!
作者: 王少雷    时间: 2012-12-31 21:24
4个线程 操作同一个资源,你不同步 加锁, 执行权当然 影响 数据的安全性。
作者: 冉世友    时间: 2012-12-31 21:46
最近我正在看张孝祥老师的Java5线程并发库,

刚好看到同步问题,你的代码里有一个静态变量x,它是被所有对象共享的数据,
当有多个线程操作共享数据时,就需要用synchronized同步。

没有同步的话,就会出现问题,而且每次运行得到的结果都不一样,因为线程抢夺
执行权是随机的。
作者: zjqlovelyy    时间: 2012-12-31 21:57
我把你的程序稍微改了下
  1. class Ticket extends Thread
  2. {
  3.         static int x= 100;
  4.         public void run()
  5.         {
  6.                        
  7.               for (;x>0 ; )
  8.               {
  9.                                         synchronized(this)
  10.                                         {
  11.                                                 System.out.println(this.getName()+"sale....."+x--);
  12.                                         }
  13.                                 }               
  14.         }
  15. }
  16. class  Test                //TicketDemo
  17. {
  18.         public static void main(String[] args)
  19.         {
  20.                 Ticket t1 = new Ticket();
  21.                 Ticket t2 = new Ticket();
  22.                 Ticket t3 = new Ticket();
  23.                 Ticket t4 = new Ticket();
  24.                 t4.start();
  25.                 t1.start();
  26.                 t2.start();
  27.                 t3.start();
  28.                
  29.         }
  30. }
复制代码

作者: 郭冰川    时间: 2012-12-31 22:22
zjqlovelyy 发表于 2012-12-31 21:57
我把你的程序稍微改了下

多谢了哈  :D
作者: zjqlovelyy    时间: 2012-12-31 23:06
郭冰川 发表于 2012-12-31 22:22
多谢了哈

:D一起加油
作者: 嘿嘿小学徒    时间: 2012-12-31 23:21
当多个线程中同时修改一个数据时,就会出现这种不安全的情况,

比如  我手里现在有10快,5个人同时都来给我 -1 操作 ,大家的初衷都是把我变成9 ,但结果我却在这个过程中有可能是9,8,7,6,5任一数字....



   解决办法:共享数据在一个时间点只能用一个线程来读取或者修改,建议学习下视频里的synchronized线程同步问题^



加油!!




作者: 何伟    时间: 2013-1-1 00:35
同步就ok了




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