Java 多線程編程--線程同步二(票數問題分析)

    前一章講解了線程不一樣步帶來的問題,最後也給你們留下了一個思考,下面是對該問題的分析。bash

@Override
    public void run(){
        String windowName=Thread.currentThread().getName();
        while(ticket.count>0){
            synchronized (ticket) {
                    ticket.count--;
                    System.out.println(windowName + "賣出一張票 剩餘票數" + ticket.count);
            }
        }
    }
}
複製代碼

    如上所示,該代碼的邏輯是經過對票數的數量進行判斷是否結束當前線程。問題就出在循環判斷這裏。     A和B兩個線程同時到達while語句,會對ticket數量進行判斷。若是數量大於0,則進入循環對ticket變量進行操做。ide

    當ticket值爲1,A和B兩個線程都運行到while語句,會發現條件知足,因而都進入了while循環體。到達synchronized語句,這時A和B兩個線程發生競爭關係,爭奪ticket對象鎖。假設A線程得到對象鎖,那麼B線程只能阻塞在synchronized(ticket)這裏。A線程繼續執行,對ticket進行減1操做,這時ticket值爲0。代碼執行完畢後,A線程釋放鎖,B取得ticket對象鎖,開始對ticket進行減1操做,但此時ticket值爲0,再繼續操做就變成了-1。因此要想獲得正確的結果,就得在對ticket進行操做前再判斷一次,修改後的代碼以下:spa

@Override
    public void run(){
        String windowName=Thread.currentThread().getName();
        while(ticket.count>0){
            synchronized (ticket) {
                if(ticket.count>0) {
                    ticket.count--;
                    System.out.println(windowName + "賣出一張票 剩餘票數" + ticket.count);
                }
            }
        }
    }
}
複製代碼
相關文章
相關標籤/搜索