黑马程序员技术交流社区

标题: 同步代码块,一个错误程序的执行结果不理解 [打印本页]

作者: 刘 佳    时间: 2012-10-13 09:40
标题: 同步代码块,一个错误程序的执行结果不理解
本帖最后由 刘 佳 于 2012-10-13 15:58 编辑

卖票的例子,我用的for循环,到同步代码块就不适用了。我的程序是错的,但是跟我想象的运行结果不同。

代码如下(代码是错的,不用纠正,我想搞清楚运行结果为什么跟我想的不同)程序一是交替执行abc线程,而程序二则跟我想的一致。这两种线程建立方式有什么不同?
*
程序一
class Ticket extends Thread
{
        private static int tick=100;
        Ticket(String name)
        {
                super(name);
        }
        Object obj=new Object();
        public void run()
        {
                synchronized (obj)        //我想的是,a线程进入到同步代码块中,b和c线程就进不来了,直到a执行完for循环,也就是从1到100张票都卖光。
                {                                     //就相当于只有a线程在卖票,bc线程没有卖票。可是结果却是abc都在卖票,我不理解明明加了同步,怎么bc还可以执行for循环的内容呢?
                        for (;tick>0 ;tick-- )
                        {
                                try{Thread.sleep(10);}catch(Exception e){}
                                System.out.println(currentThread().getName()+tick);
                        }
                }
        }
}

class  TicketDemo
{
        public static void main(String[] args)
        {
                Ticket a=new Ticket("一窗口");
                a.start();
                Ticket b=new Ticket("二窗口");
                b.start();
                Ticket c=new Ticket("三窗口");
                c.start();
        }
}

程序二
class Ticket implements Runnable
{
        private int tick=100;
        
        public void run()
        {
                synchronized (new Ticket())     
                {                                               
                        for (;tick>0 ;tick-- )
                        {
                                try{Thread.sleep(10);}catch(Exception e){}
                                System.out.println(currentThread().getName()+tick);
                        }
                }
        }
}

class  TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t=new Ticket();
                Thread a=new Thread(t);
                Thread b=new Thread(t);
                Thread c=new Thread(t);
                a.start();
                b.start();
                c.start();
        }
}





作者: 刘 佳    时间: 2012-10-13 10:28
一个回答的人都没有吗?连看帖子的人都超级少,,,肿么了是?
作者: 刘 佳    时间: 2012-10-13 11:19
求解。。。。。。
作者: 沈佳龙    时间: 2012-10-13 12:05
你上面程序一是因为你声明了三个线程,而且每个线程都是各自执行,private static int tick=100;每个线程都有一份而且不同,就算你下面用了同步和没有同步一样,因为没有其他线程和它竞争只有他一个。程序二运行成功是因为你三个线程使用的tick是同一份
Ticket t=new Ticket();
Thread a=new Thread(t);
Thread b=new Thread(t);
Thread c=new Thread(t);
三个线程竞争一个t,同步就会有效果

作者: 刘 佳    时间: 2012-10-13 12:14
沈佳龙 发表于 2012-10-13 12:05
你上面程序一是因为你声明了三个线程,而且每个线程都是各自执行,private static int tick=100;每个线程都 ...

我也体会出了这一点。可不可以理解为这是两种不同创建线程方式的不同处? 实现方式是共享一个类,而继承方式是新建很多这个类的对象,他们的内容是独立的。

毕老师说过判断是否同步有两个前提  1是有两个或者两个以上的线程 2使用的同一个锁
从上面程序是不是说,程序一使用的是三把不同的锁?只是锁的名字相同?
作者: 李润根    时间: 2012-10-13 12:25
3楼正解

程序一:每个对象对应一个线程
程序二:一个对象对应多个线程
作者: 沈佳龙    时间: 2012-10-13 14:55
刘 佳 发表于 2012-10-13 12:14
我也体会出了这一点。可不可以理解为这是两种不同创建线程方式的不同处? 实现方式是共享一个类,而继承 ...

恩 你理解的是正确的




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