黑马程序员技术交流社区

标题: 关于同步代码的问题,不懂,求帮助。 [打印本页]

作者: 叶征东    时间: 2012-7-31 22:06
标题: 关于同步代码的问题,不懂,求帮助。
package pack9;
class Tickets9 implements Runnable
{
        private int tickets=100;
        public void run()
        {
             Object obj=new Object();
             while(true)
             {
                   synchronized(obj)
                  {
                       if(tickets>0)
                      {
                             try
                            {
                               Thread.sleep(30);
                            }
                           catch(Exception e)
                           {
     
                           }
                           System.out.println(Thread.currentThread().getName()+"...sales  :"+(tickets--));
                      }
                 }
           }
     }
}
class ThreadTickets9
{
        public static void main(String[] args)
       {
              Tickets9 p=new Tickets9();
              Thread t1=new Thread(p);
              Thread t2=new Thread(p);
              Thread t3=new Thread(p);
              Thread t4=new Thread(p);
              t1.start();
              t2.start();
              t3.start();
              t4.start();
                 System.out.println("Holle world");
     }
}
刚学到了同步代码,用synchronized语句解决程序的安全问题,在没有加上synchronized语句时,是会输出 0、-1、-2的。
可是加上synchronized语句后还是会输出0、-1、-2,如图:
不知道哪儿错了,求帮助。谢谢!

作者: 郑正华    时间: 2012-7-31 22:29
本帖最后由 郑正华 于 2012-7-31 22:51 编辑

哥们,你把Object obj=new Object(); 给放在run()方法里面了,应该放在类Tickets9下!
你这样的话每个线程一运行run方法就实例化一个object对象!
synchronized(obj)←这个锁里面的obj不是同一个对象,也就相当于不是操作同一把锁,所以运行结果跟没上锁一样.....

111.png (13.19 KB, 下载次数: 11)

111.png

未命名.jpg (65.9 KB, 下载次数: 12)

未命名.jpg

作者: 张雪磊    时间: 2012-7-31 22:41
package pack9;
class Tickets9 implements Runnable
{
        private int tickets=100;
        Object obj=new Object();
        public void run()
        {
             Object obj=new Object();//这句应该放在run方法外边
             while(true)
             {
                   synchronized(obj)
                  {
                       if(tickets>0)
                      {
                             try
                            {
                               Thread.sleep(30);
                            }
                           catch(Exception e)
                           {
     
                           }
                           System.out.println(Thread.currentThread().getName()+"...sales  :"+(tickets--));
                      }
                 }
           }
     }
}
class ThreadTickets9
{
        public static void main(String[] args)
       {
              Tickets9 p=new Tickets9();
              Thread t1=new Thread(p);
              Thread t2=new Thread(p);
              Thread t3=new Thread(p);
              Thread t4=new Thread(p);
              t1.start();
              t2.start();
              t3.start();
              t4.start();
                 System.out.println("Holle world");
     }
}

同步的前提:
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。

毕老师说了如果加了同步还是出现错误,那肯定是上边两个前提至少有一个没满足。
对于上边的代码四个线程都会运行run方法,一运行,那 Object obj=new Object() 这句就执行了,相当于每个线程有一个object对象,也就是锁不同,那第二个前提就没满足,所以就出问题了。红色部分去掉,用蓝色部分就对了。



作者: 叶征东    时间: 2012-7-31 22:44
郑正华 发表于 2012-7-31 22:29
哥们,你把Object obj=new Object(); 给放在run()方法里面了,应该放在类Tickets9下!
你这样的话每个线程 ...

谢谢了,昨天也有类似的错误,把Object obj=new Object();放在了synchronized语句中,有一哥们给我指正了,从synchronized语句移到了方法中,好了。没想放到方法中还是不行,我说怎么每一次运行的时候都要CTRL+C来手动结束呢,不结束电脑就疯狂的响。谢谢了!
作者: 郑正华    时间: 2012-7-31 22:52
本帖最后由 郑正华 于 2012-7-31 22:58 编辑
叶征东 发表于 2012-7-31 22:44
谢谢了,昨天也有类似的错误,把Object obj=new Object();放在了synchronized语句中,有一哥们给我指正了 ...

呵呵,没事,
作者: 叶征东    时间: 2012-7-31 22:52
张雪磊 发表于 2012-7-31 22:41
package pack9;
class Tickets9 implements Runnable
{

我刚照着那样做,输出正常了,可为什么运行完之后,还是需要CTRL+C来手动结束啊。不然它自己不结束,电脑的CPU一直在90%
作者: 叶征东    时间: 2012-7-31 23:05
郑正华 发表于 2012-7-31 22:29
哥们,你把Object obj=new Object(); 给放在run()方法里面了,应该放在类Tickets9下!
你这样的话每个线程 ...

改好了,谢谢!
作者: 黄锐    时间: 2012-7-31 23:25
简单理解为同步锁只锁君子不锁小人。放到run方法下当然锁不住啦
作者: 张雪磊    时间: 2012-8-1 08:45
叶征东 发表于 2012-7-31 22:52
我刚照着那样做,输出正常了,可为什么运行完之后,还是需要CTRL+C来手动结束啊。不然它自己不结束,电脑 ...

因为用的是while(true)循环,循环会一直继续,老师是为了让大家看到问题这么写的。
作者: 李培根    时间: 2012-9-21 11:23
叶征东 发表于 2012-7-31 22:52
我刚照着那样做,输出正常了,可为什么运行完之后,还是需要CTRL+C来手动结束啊。不然它自己不结束,电脑 ...

因为while语句的条件一直是true  所以要手动结束 否则就是一直循环




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