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,被放入了线程等待池,就好像某人上厕所前先把门关上(上锁),完事之后再出来(解锁),然后别人就可以继续使用了。

转载于:https://www.cnblogs.com/cxq1126/p/7308955.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值