黑马程序员技术交流社区

标题: 问个线程中的小问题 [打印本页]

作者: freeboyhrk    时间: 2013-4-2 14:54
标题: 问个线程中的小问题
本帖最后由 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后运行结果会有区别,为什么会产生这种区别?
作者: 程媛媛    时间: 2013-4-2 15:25
用try,catch的原因是Thred.sleep()方法可能会出现异常,所以要用try,catch解决异常;
同步的前提是:必须有两个或者两个以上的线程;必须多个线程使用同一个锁(同一共享数据)。
因为同步函数中使用的锁是this,所以同步代码块中的锁也要使用this,如果使用obj会出现只运行同步代码块中的数据或者只运行同步函数中的数据,无法实现数据共享。
作者: 932759732    时间: 2013-4-2 15:32
本帖最后由 杨玄文 于 2013-4-2 15:33 编辑

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

然后同步是两个前提是要有多个线程,而且线程使用的锁必须一样。所以不能是obj
这一点楼上已经说到了。我就不再赘述。
作者: freeboyhrk    时间: 2013-4-2 16:03
程媛媛 发表于 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后的程序代码,运行结果是代码块和同步函数中的数据都有打印啊,只是结果不太一样,能帮详细分析下两种结果的原因吗?
作者: 蓝色骨头    时间: 2013-4-2 19:30
在  
t.flag=false;
之前只有t1线程在运行Ticket 里面的run方法,运行的是if-else的上半部分,使用的锁是obj
之后
有t1,t2两个线程在执行运行的都是if-else的下半部分,使用的锁都是t


作者: 程媛媛    时间: 2013-4-2 20:15
freeboyhrk 发表于 2013-4-2 16:03
这是同步代码块的锁换成obj后的程序代码,运行结果是代码块和同步函数中的数据都有打印啊,只是结果不太 ...

但是打印的结果出现了“Thread-1........show........0”的结果,上面设置的是tick>0,不能出现0结果,出现的原因就是使用的不是同一个锁,代码没有被同步。
作者: freeboyhrk    时间: 2013-4-3 11:02
程媛媛 发表于 2013-4-2 20:15
但是打印的结果出现了“Thread-1........show........0”的结果,上面设置的是tick>0,不能出现0结果,出 ...

嗯,谢谢...不过我的机子运行程序没有出现0的情况...不知道为什么,运行不加锁的程序,应该出现负数的也没出负数,都正常,不知道怎么回事
作者: 黄玉昆    时间: 2013-4-3 12:46
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢




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