首页 > 代码库 > Java中如何解决线程安全问题

Java中如何解决线程安全问题

给出一个问题,如下:

技术分享

解决方案如下:

 1 public class Demo_5 {
 2 
 3     public static void main(String[] args) {
 4         //创建一个窗口
 5         TicketWindow tw1=new TicketWindow();
 6 
 7         //使用三个线程同时启动
 8         Thread t1=new Thread(tw1);
 9         Thread t2=new Thread(tw1);
10         Thread t3=new Thread(tw1);
11         
12         t1.start();
13         t2.start();
14         t3.start();
15     }
16 
17 }
18 
19 //售票窗口类
20 class TicketWindow implements Runnable{
21     private int nums=2000;                         //一共2000张票
22 
23     @Override
24     public void run() {
25         while(true){        
26         
27                 if(nums>0){                        //先判断是否还有票
28                     //Thread.currentThread().getName()得到当前线程的名字
29                     System.out.println(Thread.currentThread().getName()+"在售出第"+nums+"张票");    //显示售票信息
30                 
31                     //出票的速度是一秒出一张
32                     try {
33                         Thread.sleep(1000);
34                     } catch (InterruptedException e) {
35                         e.printStackTrace();
36                     }
37                 
38                     nums--;
39                 }else{
40                     break;                            //售票结束
41                 }
42                 
43       }        
44   }    
45 }

执行这段代码发现问题,就是同一张票号可能被多个售票窗口出售,惹祸的代码就是if else语句块。

解决方法就是在需要同步的代码段用synchronized(Object){你要同步的代码}即可。

修改后代码如下:

 1 public class Demo_5 {
 2 
 3     public static void main(String[] args) {
 4         //创建一个窗口
 5         TicketWindow tw1=new TicketWindow();
 6 
 7         //使用三个线程同时启动
 8         Thread t1=new Thread(tw1);
 9         Thread t2=new Thread(tw1);
10         Thread t3=new Thread(tw1);
11         
12         t1.start();
13         t2.start();
14         t3.start();
15     }
16 
17 }
18 
19 //售票窗口类
20 class TicketWindow implements Runnable{
21     private int nums=2000;                         //一共2000张票
22 
23     @Override
24     public void run() {
25         while(true){        
26             //认为if else这段代码要保证其原子性(同步代码块)
27             synchronized (this) {
28         
29                 if(nums>0){                             //先判断是否还有票
30                     //Thread.currentThread().getName()得到当前线程的名字
31                     System.out.println(Thread.currentThread().getName()+"在售出第"+nums+"张票");    //显示售票信息
32                 
33                     //出票的速度是一秒出一张
34                     try {
35                         Thread.sleep(1000);
36                     } catch (InterruptedException e) {
37                         e.printStackTrace();
38                     }
39                 
40                     nums--;
41                 }else{
42                     break;                            //售票结束
43                 }
44                 
45             }
46         }
47     }    
48 }

执行这段代码发现出票正常了。

线程1正执行需要做同步处理的代码,线程2,3,4……blocked,被放入了线程等待池,就好像某人上厕所前先把门关上(上锁),完事之后再出来(解锁),然后别人就可以继续使用了。

Java中如何解决线程安全问题