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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© doyxy 中级黑马   /  2014-1-4 13:12  /  903 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 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. }
复制代码



评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

6 个回复

正序浏览
lwx 中级黑马 2014-1-4 20:58:38
7#
放在外面时,为全局变量,可以直接使用,放在里面后,就为局部变量了,在外界是不可使用的
回复 使用道具 举报
放在里面就不是同一把锁了
回复 使用道具 举报
感谢,了解了
回复 使用道具 举报
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对象。三个线程使用三个不同的锁,那他们弎也就就不同步了。

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
   //Object o = new Object();放在外面是成员变量,其内部方法调用成员变量都为同一个,而置于方法内就是局部变量,每调用一次方法,其内部就会去新建一个自己的局部变量,不为同一个变量无法同步

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
有点复杂
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马