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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 何仕映 于 2013-3-20 12:07 编辑

为什么加上下面注释的延时语句,多线程就不运行了呢?
求大神分析一下执行过程。
  1. /*
  2.         将买票的小实例,在建立对象的时候通过单例设计模式保证对象的唯一性
  3. */
  4. class Ticket implements Runnable
  5. {
  6.         private int num = 1000;                //设定卖票的数量

  7.         private static Ticket s = null;        //通过单例设计模式保证对象的唯一性
  8.         private Ticket(){}

  9.         public static Ticket getTicket()
  10.         {
  11.                 if (s==null)
  12.                 {

  13.                         synchronized(Ticket.class)
  14.                         {
  15.                                 System.out.println(Thread.currentThread().getName()+"-----");
  16.                                 if(s==null)
  17.                                         s =new Ticket();
  18.                         }
  19.                 }
  20.                 return s;
  21.         }
  22.         public void run()
  23.         {
  24.                 while(num>0)
  25. //                        try
  26. //                        {
  27. //                                Thread.sleep(1);                                //设定延时   为什么加上这句多线程就不运行呢?
  28. //                        }
  29. //                        catch (Exception e)
  30. //                        {
  31. //                        }
  32.                 synchronized(Ticket.class)
  33.                 {
  34.                         System.out.println(Thread.currentThread().getName()+"sale..."+num);
  35.                         --num;
  36.                 }
  37.         }
  38. }
  39. class TicketDemo
  40. {
  41.         public static void main(String[] args)
  42.         {
  43.                 Ticket a = Ticket.getTicket();
  44.                 Thread t1 = new Thread(a);
  45.                 Thread t2 = new Thread(a);
  46.                 Thread t3 = new Thread(a);

  47.                 t1.start();
  48.                 t2.start();
  49.                 t3.start();
  50.         }
  51. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

4 个回复

倒序浏览
先抢个沙发哈
回复 使用道具 举报
因为你少加了{}
在while循环的时候,加上sleep这部分代码后,while只包含sleep的代码块,来一个线程,睡了,来一个线程又睡了
  1. public void run()
  2.         {
  3.                 while(num>0){
  4.                         try
  5.                         {
  6.                                 Thread.sleep(1);                              
  7.                        }
  8.                        catch (Exception e)
  9.                         {
  10.                        }
  11.                                         synchronized(Ticket.class)
  12.                                         {
  13.                                                         System.out.println(Thread.currentThread().getName()+"sale..."+num);
  14.                                                         --num;
  15.                                         }
  16.                                 }
  17.         }
复制代码

评分

参与人数 2技术分 +1 黑马币 +6 收起 理由
何仕映 + 6
洪建超 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 张亚青 于 2013-3-20 11:09 编辑

【问题】本问题中除了楼主的疑问之外还存在一个问题,总共有两个问题:
1、程序不运行。
2、就是最后会出现一个"Thread-1sale...-1"结果 ,但有可能这是楼主故意想要的结果。


【答案】

1、对于第一个问题,之所以程序不会运行,是因为,当加上try代码块的时候
必须把try代码块和 下面的Synchronized代码块包含到一起,成为while的循环体。

  1. while (num>0)
  2. {
  3.         try
  4.         {
  5.                 Thread.sleep(1);
  6.         }
  7.         catch (Exception e)
  8.         {
  9.         }

  10.         synchronized(Ticket.class)
  11.         {
  12.                 System.out.println(Thread.currentThread().getName()+"sale..."+num);
  13.                 --num;
  14.         }
  15. }
复制代码
不然的话 就会变成 :

  1. while (num>0)//这时候while循环体只有try语句,会造成死锁而无法运行。
  2. {
  3.         try
  4.         {
  5.                 Thread.sleep(1);
  6.         }
  7.         catch (Exception e)
  8.         {
  9.         }
  10. }
  11. synchronized(Ticket.class)
  12. {
  13.     System.out.println(Thread.currentThread().getName()+"sale..."+num);
  14.     --num;
  15. }
复制代码
2、对于第二个问题,如果想要正确的代码应该改成:

  1. while (num>0)
  2. {
  3.         try
  4.         {
  5.                 Thread.sleep(1);
  6.         }
  7.         catch (Exception e)
  8.         {
  9.         }

  10.         synchronized(Ticket.class)
  11.         {
  12.                 if (num>0)//在此处再进行一次判断
  13.                 {
  14.                
  15.                 System.out.println(Thread.currentThread().getName()+"sale..."+num);
  16.                 --num;
  17.                 }
  18.         }
  19. }
复制代码

评分

参与人数 2技术分 +1 黑马币 +6 收起 理由
何仕映 + 6 很给力!
洪建超 + 1

查看全部评分

回复 使用道具 举报
张亚青 发表于 2013-3-20 11:04
【问题】本问题中除了楼主的疑问之外还存在一个问题,总共有两个问题:
1、程序不运行。
2、就是最后会出现 ...

谢谢你的回答,明白了。谢谢。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马