黑马程序员技术交流社区

标题: 多线程问题5 [打印本页]

作者: ぺsimon☆    时间: 2013-5-16 00:04
标题: 多线程问题5
本帖最后由 ぺsimon☆ 于 2013-5-16 08:47 编辑
  1. /*
  2. 继承Thread类做一个卖票程序

  3. 为什么程序的运行结果有0号票呢,哥们?
  4. */

  5. class Ticket extends Thread
  6. {
  7.         private static int ticket=100;
  8.         Object obj=new Object();

  9.         public void run()
  10.         {
  11.         while(true)
  12.         {

  13.         synchronized(obj)
  14.         {
  15.         if(ticket>0)
  16.         {
  17.         try{Thread.sleep(10);}catch(Exception e){}
  18.         System.out.println(Thread.currentThread().getName()+"..."+ticket--);
  19.         }
  20.         }
  21.         }
  22.         }
  23. }

  24. class TicketOne
  25. {
  26.         public static void main(String[] args)
  27.         {
  28.         Ticket t1=new Ticket();
  29.         t1.start();

  30.         Ticket t2=new Ticket();
  31.         t2.start();
  32.         }
  33. }
复制代码

作者: 刘学明       时间: 2013-5-16 00:13
{:soso_e140:}真不知道还是假不知道啊
作者: ぺsimon☆    时间: 2013-5-16 00:16
刘学明    发表于 2013-5-16 00:13
真不知道还是假不知道啊

是真不知道啊,哥们
作者: librazeng    时间: 2013-5-16 00:37
为什么出现0?
因为t1和t2持有不同的锁。t1和t2分别new了自己Object对象,因此synchronized(obj)持有的锁是不同的,假设当Thread-o执行到ticket=1时,if(ticket>0),满足,然后sleep(10)睡一会儿,此时Thread-1抢到执行权,通过ticket--打印1,并将ticket改为0,这时Thread睡醒了,拿着值为0的ticket输出了!
解决办法:1. 将两条线程的锁同步,可将Object变量改为静态的,即static Object obj=new Object();
               2.把if(ticket>0),改为while(ticket>0),每个线程睡醒后都要判断ticket的值。
作者: 尖卡斌引    时间: 2013-5-16 02:15
此程序的第33和36行分别创建了两个Ticket对象 t1和t2.
每个Ticket对象中都有一个私有的 ticket =100. 这就相当于有了200张票。
而且每个对象都有一个  obj 对象  这就使得线程使用的锁不是同一个锁。
所以就出现了 同样的票被卖了两次和出现0号票的情况
修改后的主函数代码
public static void main(String[] args)
{  
       Ticket t = new Ticket();   //创建一个Ticket对象,保证了资源(票)的唯一,和锁的唯一;

       Thread t1 = new Thread(t);     //创建两个线程,操作同一个资源(票)使用的也是同一个锁obj;

       Thread t2 = new Thread(t);

        t1.start();

        t2.start();
}

作者: ぺsimon☆    时间: 2013-5-16 08:47
看来我对多线程掌握得真的不是那么好啊,谢谢大家的解答,我明白了




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