首頁  >  文章  >  Java  >  Java中關於線程安全性問題的解決詳解

Java中關於線程安全性問題的解決詳解

黄舟
黄舟原創
2017-08-09 09:15:471654瀏覽

給出一個問題,如下:

解決方案如下:

public class Demo_5 {

    public static void main(String[] args) {
        //创建一个窗口
        TicketWindow tw1=new TicketWindow();

        //使用三个线程同时启动
        Thread t1=new Thread(tw1);
        Thread t2=new Thread(tw1);
        Thread t3=new Thread(tw1);
        
        t1.start();
        t2.start();
        t3.start();
    }

}

//售票窗口类
class TicketWindow implements Runnable{
    private int nums=2000;                         //一共2000张票

    @Override
    public void run() {
        while(true){        
        
                if(nums>0){                        //先判断是否还有票
                    //Thread.currentThread().getName()得到当前线程的名字
                    System.out.println(Thread.currentThread().getName()+"在售出第"+nums+"张票");    //显示售票信息
                
                    //出票的速度是一秒出一张
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                
                    nums--;
                }else{
                    break;                            //售票结束
                }
                
      }        
  }    
}

執行這段程式碼發現問題,就是同一張票號可能被多個售票窗口出售,惹禍的代碼就是if else語句塊。

解決方法就是在需要同步的程式碼片段用synchronized(Object){你要同步的程式碼}即可。

修改後程式碼如下:

public class Demo_5 {

    public static void main(String[] args) {
        //创建一个窗口
        TicketWindow tw1=new TicketWindow();

        //使用三个线程同时启动
        Thread t1=new Thread(tw1);
        Thread t2=new Thread(tw1);
        Thread t3=new Thread(tw1);
        
        t1.start();
        t2.start();
        t3.start();
    }

}

//售票窗口类
class TicketWindow implements Runnable{
    private int nums=2000;                         //一共2000张票

    @Override
    public void run() {
        while(true){        
            //认为if else这段代码要保证其原子性(同步代码块)
            synchronized (this) {
        
                if(nums>0){                             //先判断是否还有票
                    //Thread.currentThread().getName()得到当前线程的名字
                    System.out.println(Thread.currentThread().getName()+"在售出第"+nums+"张票");    //显示售票信息
                
                    //出票的速度是一秒出一张
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                
                    nums--;
                }else{
                    break;                            //售票结束
                }
                
            }
        }
    }    
}

執行這段程式碼發現出票正常了。

線程1正執行需要做同步處理的程式碼,線程2,3,4…blocked,被放入了線程等待池,就好像某人上廁所前先把門關上(上鎖),完事之後再出來(解鎖),然後別人就可以繼續使用了。

以上是Java中關於線程安全性問題的解決詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn