黑马程序员技术交流社区

标题: 多线程安全问题 [打印本页]

作者: 董志超    时间: 2012-9-27 15:20
标题: 多线程安全问题
本帖最后由 董志超 于 2012-9-28 06:00 编辑

class Ticket implements Runnable
{
        private int tick = 100;
        //Object obj = new Object();
        public void run()
        {
                while(true)
                {
                        synchronized(new Object())//红色部分不注释,同步中传obj,无安全问题。红色部分注释后,同步中传new Object(),却出了安全问题。why?
                        {
                                if (tick>0)
                                {
                                        try{Thread.sleep(10);}catch(Exception e){}
                                        System.out.println(Thread.currentThread().getName()+"..sale.."+tick--);
                                }
                        }
                        
                }
               
        }
}
class  TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t = new Ticket();

                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                Thread t3 = new Thread(t);
                Thread t4 = new Thread(t);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}


作者: 史龙贤    时间: 2012-9-27 15:29
保证同步中使用同一把锁,这把锁可以是任意对象,所以用上帝他老人家来当所是可以的!你传obj,obj指向new Object()这个对象,这是同一个对象。当注释Object obj = new Object()后,传new Object()作为锁,匿名对象作为锁,每个进程进来,都new一把新锁,不是同一个对象,同步自然失败!
作者: 罗磊    时间: 2012-9-27 15:32
class Ticket implements Runnable
{
        private int tick = 100;
        //Object obj = new Object();
        public void run()
        {
                while(true)
                {
                        synchronized(new Object())//红色部分不注释,同步中传obj,无安全问题。红色部分注释后,同步中传new Object(),却出了安全问题。why?
                                      //纠正一下!红色部分你注不注释,都有安全问题!原因是你的锁 用的是new Object()   所以你每次线程进入都会创建新对象 这样
                                      //锁拿到的并不是同一个对象!
                                     //所以,不要这么定义!就用(obj )就好!
                        {
                                if (tick>0)
                                {
                                        try{Thread.sleep(10);}catch(Exception e){}
                                        System.out.println(Thread.currentThread().getName()+"..sale.."+tick--);
                                }
                        }
                        
                }
               
        }
}
class  TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t = new Ticket();

                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                Thread t3 = new Thread(t);
                Thread t4 = new Thread(t);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}





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