黑马程序员技术交流社区

标题: 同步代码块的“锁”是哪一个? [打印本页]

作者: 王杰    时间: 2012-3-13 20:27
标题: 同步代码块的“锁”是哪一个?
  1. /*
  2. *四个售票员一起同步发售100张票;
  3. */
  4. package day11;
  5. class Ticket extends Thread
  6. {
  7.         private static int Tick = 100;
  8.         Object obj = new Object();
  9.         public void run()//这个方法不是静态的。
  10.         {                                        //那么他的锁可以是自定义的obj也可以是this。对吧?
  11.                 while(true)
  12.                 {
  13.                         synchronized(Ticket.class)//但是这儿如果放入obj或者this,会出现安全隐患!
  14.                         {                                                        //卖出负票!只有放Ticket.class时运行正常!
  15.                                 if(Tick>0)
  16.                                 {
  17.                                         try{Thread.sleep(10);}catch(Exception e){}
  18.                                         System.out.println(Thread.currentThread().getName()+"....."+Tick--);
  19.                                 }
  20.                         }
  21.                 }
  22.                        
  23.         }


  24.                
  25. }

  26. class TicketDemo1
  27. {
  28.         public static void main(String[] a)
  29.         {

  30.                 Ticket t1 = new Ticket();
  31.                 Ticket t2 = new Ticket();
  32.                 Ticket t3 = new Ticket();
  33.                 Ticket t4 = new Ticket();

  34.                 t1.start();
  35.                 t2.start();
  36.                 t3.start();
  37.                 t4.start();       
  38.         }
  39. }
复制代码

作者: 王杰    时间: 2012-3-13 20:35
自己顶一下,在线求解
作者: 张一凡    时间: 2012-3-13 20:40
你这个锁已经很明显了,也就是类名。
作者: 崔岩    时间: 2012-3-13 20:52
本帖最后由 崔岩 于 2012-3-13 22:11 编辑

你NEW了4个 Ticket, 这样呢,每个对象里都有一个独立的obj ,this指代的也是这个独立的对象,所以你这个写法呢,会出现4个卖票的用的不是一个锁,所以互相之间没有制约。
建议你把Ticket继承runnable, 只new一个Ticket,然后new4个线程,把同一个Ticket传进去。这样就能解决了.
     另外想补充几句,面向对象的语言之所以广为接受,不光是我们在设计的时候可以用现实生活中的实体做参照,而且在出现了问题以后,由于设计时是参照现实生活中活生生的事物,所以解决问题的时候更应该思考下在现实生活中,事物是如何运作的,有什么特性。
   就像你这个例子,Ticket当做火车票,那它就是对应一个火车的座位数目,而卖票的窗口是有多个。这时候票的数据应该只有一份,并且是排它的(就是有一个窗口在改写这个数据的时候,别的窗口不能访问,否则就会出现一票多卖的情况),如果按照这个思维过程来想,那在设计Ticket类的时候,我们就不会在new出多个Ticket了。
作者: 张锐    时间: 2012-3-13 20:53
因为this和obj都不是唯一的,每次new都会有一个新的出来,所以实现不了锁的效果,如果你把obj修饰为static应该就可以了。
作者: 王杰    时间: 2012-3-13 20:57
哦哦 我怎么没注意到呢 哈哈 明白了
作者: 泮和顺    时间: 2012-3-13 20:59
是不是同步代码块锁了整块所以 if语句块里没有起到同步作用 多了一对{}
作者: 王杰    时间: 2012-3-13 21:00
张锐 发表于 2012-3-13 20:53
因为this和obj都不是唯一的,每次new都会有一个新的出来,所以实现不了锁的效果,如果你把obj修饰为static ...

嗯嗯 明白了  忽略了每一次new都会产生一个obj。谢谢
作者: 泮和顺    时间: 2012-3-13 21:48
王杰 发表于 2012-3-13 21:00
嗯嗯 明白了  忽略了每一次new都会产生一个obj。谢谢

synchronized(this)前再加个if(Tick>0)
也行多次判断...
作者: 袁野    时间: 2012-3-13 22:10
只要是同一个对象就是一个锁




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