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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 郭冰川 于 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是咋回事呢?

评分

参与人数 1技术分 +1 收起 理由
奋斗的青春 + 1 赞一个!

查看全部评分

11 个回复

正序浏览
同步就ok了
回复 使用道具 举报
当多个线程中同时修改一个数据时,就会出现这种不安全的情况,

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



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



加油!!



评分

参与人数 1技术分 +1 收起 理由
奋斗的青春 + 1 赞一个!

查看全部评分

回复 使用道具 举报
郭冰川 发表于 2012-12-31 22:22
多谢了哈

:D一起加油
回复 使用道具 举报
zjqlovelyy 发表于 2012-12-31 21:57
我把你的程序稍微改了下

多谢了哈  :D
回复 使用道具 举报
我把你的程序稍微改了下
  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. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
奋斗的青春 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
最近我正在看张孝祥老师的Java5线程并发库,

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

没有同步的话,就会出现问题,而且每次运行得到的结果都不一样,因为线程抢夺
执行权是随机的。

评分

参与人数 1技术分 +1 收起 理由
奋斗的青春 + 1 赞一个!

查看全部评分

回复 使用道具 举报
4个线程 操作同一个资源,你不同步 加锁, 执行权当然 影响 数据的安全性。
回复 使用道具 举报
你多运行几次,还会有不同的结果。需要同步的!
回复 使用道具 举报
赵彦辉 发表于 2012-12-31 20:46
多线程运行中的安全问题:
问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行 ...

我试过加同步代码块,结果一样,而且for循环那只有一个语句不会被分开读,也就不存在代码安全问题,还有就是如果是因为代码安全问题的话,为什么只有100重复,后面的却不出现重复的情况呢
回复 使用道具 举报
多线程运行中的安全问题:
问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完
另一个线程参与进来执行,导致共享数据的错误。
   解决办法:对多条操作共享数据的语句,只能让一个线程执行完毕,在执行过程中,其他线程不可以参与执行。
    可以只用synchronized 方法或者代码块来出来,也可以使用 lock 来解决这样的问题
建议你多往后面学习,前面遇到的这些问题就迎刃而解了

评分

参与人数 1技术分 +1 收起 理由
奋斗的青春 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 马志军 于 2012-12-31 20:18 编辑

没有同步
多个线程执行共享数据,一个线程可能对多条语句执行了一部分,另一个线程又执行部分,就会发生安全问题。
比如线程3,遇到for,x初始赋为100,还没输出呢,线程0抢到执行权,又for,x为100,然后线程3执行了输出100,线程0因为开始已经走过for里面了,x是100,所以它也输出100
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马