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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© freeboyhrk 中级黑马   /  2013-4-2 14:54  /  1480 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 freeboyhrk 于 2013-4-6 11:00 编辑

class Ticket implements Runnable
{
        private  int tick = 100;
        Object obj = new Object();
        boolean flag = true;
        public  void run()
        {
                if(flag)
                {
                        while(true)
                        {
                                synchronized(this)
                                {
                                        if(tick>0)
                                        {
                                                try{Thread.sleep(10);}catch(Exception e){}
                                                System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                                        }
                                }
                        }
                }
                else
                        while(true)
                                show();
        }
        public synchronized void show()//this
        {
                if(tick>0)
                {
                        try{Thread.sleep(10);}catch(Exception e){}
                        System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
                }
        }
}

这段代码里,为什么要try,catch?  还有,同步代码块中的锁改成obj后运行结果会有区别,为什么会产生这种区别?

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

7 个回复

倒序浏览
用try,catch的原因是Thred.sleep()方法可能会出现异常,所以要用try,catch解决异常;
同步的前提是:必须有两个或者两个以上的线程;必须多个线程使用同一个锁(同一共享数据)。
因为同步函数中使用的锁是this,所以同步代码块中的锁也要使用this,如果使用obj会出现只运行同步代码块中的数据或者只运行同步函数中的数据,无法实现数据共享。

评分

参与人数 1技术分 +2 收起 理由
滔哥 + 2

查看全部评分

回复 使用道具 举报
本帖最后由 杨玄文 于 2013-4-2 15:33 编辑

因为你是复写的Runnable接口的run方法。
而这个方法本身是不会抛异常的。
所以在这里只能try,catch
而不能抛出去

然后同步是两个前提是要有多个线程,而且线程使用的锁必须一样。所以不能是obj
这一点楼上已经说到了。我就不再赘述。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
程媛媛 发表于 2013-4-2 15:25
用try,catch的原因是Thred.sleep()方法可能会出现异常,所以要用try,catch解决异常;
同步的前提是:必须 ...
  1. class ThisLockDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Ticket t=new Ticket();
  6.                 Thread t1=new Thread(t);
  7.                 Thread t2=new Thread(t);
  8.                 t1.start();
  9.                 try
  10.                 {
  11.                         Thread.sleep(10);
  12.                 }
  13.                 catch (Exception e)
  14.                 {
  15.                 }
  16.                 t.flag=false;
  17.                 t2.start();
  18.                
  19.         }
  20. }

  21. class Ticket implements Runnable
  22. {
  23.         private int tick = 100;
  24.         Object obj = new  Object();
  25.         boolean flag = true;
  26.         public void run()
  27.         {
  28.                 if (flag)
  29.                 {
  30.                         while (true)
  31.                         {
  32.                                 synchronized(obj)
  33.                                 {
  34.                                         if (tick>0)
  35.                                         {
  36.                                                 try
  37.                                                 {
  38.                                                         Thread.sleep(10);
  39.                                                 }
  40.                                                 catch (Exception e)
  41.                                                 {
  42.                                                 }
  43.                                                 System.out.println(Thread.currentThread().getName()+"Sale:"+tick--);
  44.                                         }

  45.                                 }
  46.                         }
  47.                 }
  48.                 else
  49.                         while(true)
  50.                                 show();
  51.         }
  52.         public synchronized void show()
  53.         {
  54.                 if(tick>0)
  55.                 {
  56.                         try
  57.                         {
  58.                                 Thread.sleep(10);
  59.                         }
  60.                         catch (Exception e)
  61.                         {
  62.                         }
  63.                         System.out.println(Thread.currentThread().getName()+"........show........"+tick--);
  64.                 }
  65.         }
  66. }
复制代码
这是同步代码块的锁换成obj后的程序代码,运行结果是代码块和同步函数中的数据都有打印啊,只是结果不太一样,能帮详细分析下两种结果的原因吗?

评分

参与人数 1技术分 +3 收起 理由
滔哥 + 3

查看全部评分

回复 使用道具 举报
在  
t.flag=false;
之前只有t1线程在运行Ticket 里面的run方法,运行的是if-else的上半部分,使用的锁是obj
之后
有t1,t2两个线程在执行运行的都是if-else的下半部分,使用的锁都是t

回复 使用道具 举报
freeboyhrk 发表于 2013-4-2 16:03
这是同步代码块的锁换成obj后的程序代码,运行结果是代码块和同步函数中的数据都有打印啊,只是结果不太 ...

但是打印的结果出现了“Thread-1........show........0”的结果,上面设置的是tick>0,不能出现0结果,出现的原因就是使用的不是同一个锁,代码没有被同步。
回复 使用道具 举报
程媛媛 发表于 2013-4-2 20:15
但是打印的结果出现了“Thread-1........show........0”的结果,上面设置的是tick>0,不能出现0结果,出 ...

嗯,谢谢...不过我的机子运行程序没有出现0的情况...不知道为什么,运行不加锁的程序,应该出现负数的也没出负数,都正常,不知道怎么回事
回复 使用道具 举报
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马