synchronized理解與總結
阿新 • • 發佈:2018-03-26
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理解與總結