1. 程式人生 > >synchronized理解與總結

synchronized理解與總結

public mar 環境 new t 觀察 初始 down ble ()

synchronized理解與總結

  • 第一次實現的代碼分析(不一定哪個線程搶到任務,搶到的線程會一直把任務執行完,不給其它線程機會)

    環境模擬:假設車站的車票開放給三個票販子賣
    class MyThread implements Runnable {
    private int ticket = 10 ; //初始設置票數為10
    @Override
    public void run() {       //車站的賣票系統
        System.out.println(Thread.currentThread().getName() + "報道,準備搶任務") ;  //誰第一個報道,誰就搶到了機會
        synchronized (this) {
            while(this.ticket > 0) {  //觀察循環的位置,一旦某一個票販子(線程)搶到了機會,就會一直循環賣完票為止,過程中一直在執行循環體,不會跳出synchronized鎖,別人再沒有機會搶了
                System.out.println(Thread.currentThread().getName() + "賣出一張票,剩余票數" + --this.ticket + "張。") ;
            }
        }
    }
    }
    以上代碼的確解決了數據安全問題,但是又回歸到了單線程時的現象,只能一個線程程序執行到底,但是是哪個線程並不確定,要看哪個線程能搶到
  • 改進後的代碼分析(所有線程都參與了計算)

    class MyThread implements Runnable {
    private int ticket = 10 ; //初始設置票數為10
    @Override
    public void run() {       //車站的賣票系統
        System.out.println(Thread.currentThread().getName() + "報道,準備搶任務") ;  //第一個報道的就搶到第一次機會,但後面幾次依然要重新搶機會
        while(this.ticket > 0) {
            synchronized (this) {  //主要是觀察synchronized在程序中出現的位置
                if (this.ticket > 0 ) System.out.println(Thread.currentThread().getName() + "賣出一張票,剩余票數" + --this.ticket + "張。") ;
            }
        }
    }
    }
    為了數據安全,只能允許同一時間一個線程運行,但是每一次循環所有線程都將再次有機會搶到任務,所以結果是多個線程參與了計算。
  • 附:主方法測試代碼

    public class Hello {
    public static void main(String[] args) {
    Runnable ru = new MyThread() ;
        new Thread(ru,"票販子1").start() ;
        new Thread(ru,"票販子2").start() ;
        new Thread(ru,"票販子3").start() ;
    }
    }

synchronized理解與總結