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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王杰 黑马帝   /  2012-3-13 20:27  /  2139 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  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. }
复制代码

9 个回复

倒序浏览
自己顶一下,在线求解
回复 使用道具 举报
你这个锁已经很明显了,也就是类名。
回复 使用道具 举报
本帖最后由 崔岩 于 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:58

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
因为this和obj都不是唯一的,每次new都会有一个新的出来,所以实现不了锁的效果,如果你把obj修饰为static应该就可以了。

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
哦哦 我怎么没注意到呢 哈哈 明白了
回复 使用道具 举报
是不是同步代码块锁了整块所以 if语句块里没有起到同步作用 多了一对{}
回复 使用道具 举报
王杰 黑马帝 2012-3-13 21:00:38
8#
张锐 发表于 2012-3-13 20:53
因为this和obj都不是唯一的,每次new都会有一个新的出来,所以实现不了锁的效果,如果你把obj修饰为static ...

嗯嗯 明白了  忽略了每一次new都会产生一个obj。谢谢
回复 使用道具 举报
王杰 发表于 2012-3-13 21:00
嗯嗯 明白了  忽略了每一次new都会产生一个obj。谢谢

synchronized(this)前再加个if(Tick>0)
也行多次判断...
回复 使用道具 举报
袁野 黑马帝 2012-3-13 22:10:56
10#
只要是同一个对象就是一个锁
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马