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

  • 相关阅读:
    R语言做文本挖掘 Part4文本分类
    在VS2005中使用原来的IIS调试Web程序(像VS2003一样)
    “提高一下dotnet程序的效率一”中关于exception的问题
    asp.net Cookies 转码的问题 中文丢失
    静态构造函数
    js在firefox中的问题
    模板引擎的一种实现
    .NET面试题,看看你的水平[转]
    转载 软件架构师应该具备的素质(Enterprise Solution Architects and Leadership)
    用正则表达式提取url中的Querystring参数
  • 原文地址:https://www.cnblogs.com/cxq1126/p/7308955.html
Copyright © 2011-2022 走看看