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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 叶征东 中级黑马   /  2012-7-31 22:06  /  2429 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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,如图:
不知道哪儿错了,求帮助。谢谢!

评分

参与人数 1技术分 +1 收起 理由
包晗 + 1 加油

查看全部评分

9 个回复

倒序浏览
本帖最后由 郑正华 于 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

评分

参与人数 1技术分 +1 收起 理由
包晗 + 1 赞一个!

查看全部评分

回复 使用道具 举报
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对象,也就是锁不同,那第二个前提就没满足,所以就出问题了。红色部分去掉,用蓝色部分就对了。


评分

参与人数 1技术分 +1 收起 理由
包晗 + 1 赞一个!

查看全部评分

回复 使用道具 举报
郑正华 发表于 2012-7-31 22:29
哥们,你把Object obj=new Object(); 给放在run()方法里面了,应该放在类Tickets9下!
你这样的话每个线程 ...

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

呵呵,没事,
回复 使用道具 举报
张雪磊 发表于 2012-7-31 22:41
package pack9;
class Tickets9 implements Runnable
{

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

改好了,谢谢!
回复 使用道具 举报
黄锐 初级黑马 2012-7-31 23:25:41
8#
简单理解为同步锁只锁君子不锁小人。放到run方法下当然锁不住啦
回复 使用道具 举报
叶征东 发表于 2012-7-31 22:52
我刚照着那样做,输出正常了,可为什么运行完之后,还是需要CTRL+C来手动结束啊。不然它自己不结束,电脑 ...

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

因为while语句的条件一直是true  所以要手动结束 否则就是一直循环
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马