黑马程序员技术交流社区

标题: 请教同步代码块的问题 [打印本页]

作者: doyxy    时间: 2014-1-4 13:12
标题: 请教同步代码块的问题
本帖最后由 doyxy 于 2014-1-4 18:38 编辑

建立的对象放在外面时正常,如果放在里面,sychronized不起作用,这是怎么回事呢?

  1. class Ticket implements Runnable
  2. {
  3.         private int tick = 100;
  4.         //Object o = new Object();
  5.         
  6.         public void run()
  7.         {
  8.                 Object o = new Object();
  9.                 while (true)
  10.                 {
  11.                         
  12.                         synchronized (o)
  13.                         {
  14.                                 if (tick>0)
  15.                                 {
  16.                                         try
  17.                                                 {
  18.                                                         Thread.sleep(10);
  19.                                                 }
  20.                                         catch (Exception e)
  21.                                                 {
  22.                                                 }
  23.                                         System.out.println(Thread.currentThread().getName() + "sale:" + tick--);
  24.                                 }
  25.                         }
  26.                 }
  27.         }

  28. }
  29. class TicketDemo
  30. {
  31.         public static void main(String[] args)
  32.         {
  33.                 Ticket t = new Ticket();

  34.                 Thread t1 = new Thread(t);
  35.                 Thread t2 = new Thread(t);
  36.                 Thread t3 = new Thread(t);

  37.                 t1.start();
  38.                 t2.start();
  39.                 t3.start();
  40.                
  41.         }
  42. }
复制代码




作者: 李兴    时间: 2014-1-4 15:47
有点复杂
作者: 午夜b'Boy    时间: 2014-1-4 15:55
   //Object o = new Object();放在外面是成员变量,其内部方法调用成员变量都为同一个,而置于方法内就是局部变量,每调用一次方法,其内部就会去新建一个自己的局部变量,不为同一个变量无法同步
作者: 李兴    时间: 2014-1-4 16:09
t1.start(); t2.start();t3.start();都会调用他们各自的run方法。

t1,t2,t3运行的目标对象都是Ticket类型的t实例,
当实例t创建时,放在run方法外面的Object o就只初始化一次,所以t1,t2,t3就使用同一个锁对象。所以这3个线程是同步的。

而如果将锁(Object o)放在run方法内部进行初始化,当Ticket t进行初始化时,不会调用Ticker类内部的run方法,也没有锁的实例,当t1.start();运行时,就会调用run方法对Object o这个局部变量进行初始化,会产生一块内存来存储属于t1线程的o对象,但当t2.start();运行时,也会调用run方法对Object o这个局部变量进行初始化,会产生另一块内存来存储属于t2线程的o对象,t3也会产生另一块内存来存储属于t3线程的o对象。三个线程使用三个不同的锁,那他们弎也就就不同步了。
作者: doyxy    时间: 2014-1-4 18:38
感谢,了解了
作者: 道逍云心    时间: 2014-1-4 19:32
放在里面就不是同一把锁了
作者: lwx    时间: 2014-1-4 20:58
放在外面时,为全局变量,可以直接使用,放在里面后,就为局部变量了,在外界是不可使用的




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