首页 > 代码库 > 【JAVA多线程安全问题解析】

【JAVA多线程安全问题解析】

一、问题的提出

以买票系统为例:

 1 class Ticket implements Runnable 2 { 3     public int sum=10; 4     public void run() 5     { 6         while(true) 7         { 8             if(sum>0) 9             {10                 System.out.println(Thread.currentThread().getName()+":"+sum--);11             }12         }13     }14 }15 public class Demo16 {17     public static void main(String args[])18     {19         Ticket t=new Ticket();20         new Thread(t).start();21         new Thread(t).start();22         new Thread(t).start();23         new Thread(t).start();24     }25 }
View Code

这个代码有问题。仔细分析可以知道,如果四个线程同时进入了run方法中,假设当时sum==1,则第一个线程可以进入if块中,但是如果CPU突然切换到了其他线程,那么第一个线程将会等待CPU执行权,但是并没有改变sum的值,此时sum仍然是1;同理,假设极端情况发生了,即第2、3个线程均进入了if块,而且均在改变sum值之前就并指运行,等待CPU执行权,那么第四个线程改变完sum的值称为0之后,其余三个线程会将sum的值变为-1,-2,-3(但是输出只能到-2),很明显的,问题发生了,虽然几率不大,但是一旦发生就是致命的问题。

使用Thread.sleep()方法可以暂停线程的执行,通过输出即可检验。

 1 class Ticket implements Runnable 2 { 3     public int sum=10; 4     public void run() 5     { 6         while(true) 7         { 8             if(sum>0) 9             {10                 try11                 {12                     Thread.sleep(50);13                 }14                 catch(InterruptedException e){}15                 System.out.println(Thread.currentThread().getName()+":"+sum--);16             }17 18         }19     }20 }21 public class Demo22 {23     public static void main(String args[])24     {25         Ticket t=new Ticket();26         new Thread(t).start();27         new Thread(t).start();28         new Thread(t).start();29         new Thread(t).start();30     }31 }
View Code

运行结果:

注意使用sleep方法产生的异常只能捕获不能抛出。

 

【JAVA多线程安全问题解析】