黑马程序员技术交流社区

标题: 验证同步函数的锁为this [打印本页]

作者: 黄长利    时间: 2012-3-28 22:56
标题: 验证同步函数的锁为this
class Ticket implements Runnable
{
        private int ticket = 100;
        Object obj = new Object();
        boolean flag = true;
        public void run()
        {
                if(flag)
                {
                        while(true)
                        {
                                synchronized(obj)
                                {
                                        if(ticket>0)
                                        {
                                                try
                                                {
                                                        Thread.sleep(10);
                                                }
                                                catch (Exception e)
                                                {
                                                }                                       
                                                System.out.println(Thread.currentThread().getName()+"同步代码块卖票"+ticket--);
                                        }
                                }
                        }
                }
                else
                {
                        while(true)
                        {
                                show();
                        }
                }
        }
        public synchronized void show()
        {
               
                        if(ticket>0)
                        {
                                try
                                {
                                        Thread.sleep(10);
                                }
                                catch (Exception e)
                                {
                                }                                       
                                System.out.println(Thread.currentThread().getName()+"构造函数卖票"+ticket--);
                        }
        }
}

class ThisLockDemo
{
        public static void main(String[] args)
        {
                Ticket t = new Ticket();
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
               
                t1.start();
                try
                {
                        Thread.sleep(10);
                }
                catch (Exception e)
                {

                }
                t.flag = false;
                t2.start();

        }
}

此代码验证同步函数的锁是 this 时,当将 if 语句内的锁设为 obj 对象时,最后的运行结果出现票号为 0 的的时候,是在哪里出现了切换,导致没能实现同步,有些晕了,希望大家给小弟解释一下,谢谢了。。。
作者: yangshang1    时间: 2012-3-29 06:59
两个进程相互修改private int ticket = 100;线程A减减时B也减减
导致出现了0当然都在 if(ticket>0)这里时
作者: 方江    时间: 2012-3-29 08:32
class Ticket implements Runnable
{
        private int ticket = 100;
        Object obj = new Object();
        boolean flag = true;
        public void run()
        {
                if(flag)
                {
                        while(true)
                        {
                                synchronized(obj)
                                {
                                        if(ticket>0)
                                        {
                                                try
                                                {
                                                        Thread.sleep(10);
                                                }
                                                catch (Exception e)
                                                {
                                                }                                       
                                                System.out.println(Thread.currentThread().getName()+"同步代码块卖票"+ticket--);
                                        }
                                }
                        }
                }
                else
                {
                        while(true)
                        {
                                show();
                        }
                }
        }
        public  void show()
        {
               
                        if(ticket>0)
                        {
                                try
                                {
                                        Thread.sleep(10);
                                }
                                catch (Exception e)
                                {
                                }                                       
                                System.out.println(Thread.currentThread().getName()+"构造函数卖票"+ticket--);
                        }
        }
}

class ThisLockDemo
{
        public static void main(String[] args)
        {
                Ticket t = new Ticket();
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
               
                t1.start();
                try
                {
                        Thread.sleep(10);
                }
                catch (Exception e)
                {

                }
                t.flag = false;
                t2.start();

        }
}


你只要把show里面的锁去掉就行,因为你前面在调用show的时候已经同步了,如果你在后面再同步一次。那么就直接跑0了~~
作者: 田啸    时间: 2012-3-29 08:54
因为你的show函数持有的锁是当前对象,而你前面的代码中 synchronized(obj),这里的锁是obj,用了不同的锁,所以无法实现同步
作者: 胡元    时间: 2012-3-29 10:24
两个线程操作一个资源,要想无错误出现,必须使用同一把锁,你用了两个,一个当前对象this,一个是obj!!所以设置obj锁时候出现错误!而且这个代码不好验证同步函数锁是this,用这个:
class Ticket implements Runnable
{
        private int ticket = 100;
        Object obj = new Object();
        boolean flag = true;
        public void run()
        {
               
                        while(true)
                        {
                                show();
                        }
               
        }
        public synchronized void show()
        {
               
                        if(ticket>0)
                        {
                                try
                                {
                                        Thread.sleep(10);
                                }
                                catch (Exception e)
                                {
                                }                                       
                                System.out.println((Thread.currentThread()==this)+"构造函数卖票"+ticket--);
                        }
        }
}

class ThisLockDemo
{
        public static void main(String[] args)
        {
                Ticket t = new Ticket();
                Thread t1 = new Thread(t);
               
               
                t1.start();
               

        }
}
当打印出“true同步函数售票,ticket--”时就证明了同步函数锁是this





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