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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

存在安全问题的多线程代码:
  1. class Ticket implements Runnable
  2. {
  3.         private int tick = 100;
  4.         //Object obj = new Object();
  5.         public void run()
  6.         {
  7.                 while(true)
  8.                 {
  9.                         if(tick>0)
  10.                         {
  11.                                 try{Thread.sleep(10);}catch(Exception e){}
  12.                                 System.out.println(Thread.currentThread().getName()+"...sale: "+tick--);
  13.                         }
  14.                                
  15.                 }
  16.         }
  17. }

  18. class TicketDemo2
  19. {
  20.         public static void main(String[] args)
  21.         {
  22.                 Ticket t = new Ticket();
  23.                 Thread t1 = new Thread(t);
  24.                 Thread t2 = new Thread(t);
  25.                 Thread t3 = new Thread(t);
  26.                 Thread t4 = new Thread(t);
  27.                 t1.start();
  28.                 t2.start();
  29.                 t3.start();
  30.                 t4.start();
  31.         }
  32. }
复制代码

编译运行结果(截取末尾的语句):Thread-2...sale: 10
Thread-1...sale: 9
Thread-3...sale: 8
Thread-0...sale: 7
Thread-2...sale: 6
Thread-1...sale: 5
Thread-3...sale: 4
Thread-0...sale: 3
Thread-2...sale: 2
Thread-1...sale: 1
Thread-3...sale: 0
Thread-2...sale: -1
Thread-0...sale: -2


使用同步代码块的方法:
  1. class Ticket implements Runnable
  2. {
  3.         private int tick = 100;
  4.         Object obj = new Object();
  5.         public void run()
  6.         {
  7.                 while(true)
  8.                 {
  9.                         synchronized(obj)
  10.                         {
  11.                                 if(tick>0)
  12.                                 {
  13.                                         try{Thread.sleep(10);}catch(Exception e){}
  14.                                         System.out.println(Thread.currentThread().getName()+"...sale: "+tick--);
  15.                                 }
  16.                         }       
  17.                 }
  18.         }
  19. }

  20. class TicketDemo2
  21. {
  22.         public static void main(String[] args)
  23.         {
  24.                 Ticket t = new Ticket();
  25.                 Thread t1 = new Thread(t);
  26.                 Thread t2 = new Thread(t);
  27.                 Thread t3 = new Thread(t);
  28.                 Thread t4 = new Thread(t);
  29.                 t1.start();
  30.                 t2.start();
  31.                 t3.start();
  32.                 t4.start();
  33.         }
  34. }
复制代码

编译运行结果出现了单线程的情况,虽然负数消失了。
Thread-0...sale: 10
Thread-0...sale: 9
Thread-0...sale: 8
Thread-0...sale: 7
Thread-0...sale: 6
Thread-0...sale: 5
Thread-0...sale: 4
Thread-0...sale: 3
Thread-0...sale: 2
Thread-0...sale: 1


表示非常困惑?同步代码块的方式出错了还是其他方面?

2 个回复

倒序浏览
不一定是代码出了问题,CPU的执行速度是非常快的,你可以现把票改成1000张看下结果再确认是不是只出现了单线程
回复 使用道具 举报
黄蒙 发表于 2015-8-24 15:58
不一定是代码出了问题,CPU的执行速度是非常快的,你可以现把票改成1000张看下结果再确认是不是只出现了单 ...

刚刚试了一下确实可行,谢谢解答~~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马