《java併發程式設計實戰》之 執行緒安全性
阿新 • • 發佈:2018-12-01
1.執行緒安全性
當多個執行緒訪問某個類時,不管執行時環境採用何種排程方式或者這些執行緒將如何交替執行,並且在主調程式碼中不需要任何額外的同步或協同,這個類都能表現出正確的行為,那麼這個類就是執行緒安全的。
無狀態物件一定是執行緒安全的,何為無狀態,就是類中不包含任何域,也不包含各種其他類的飲用,就只有區域性變數 。
2.原子性
執行緒中的 ++count 或者 count++ 那都非原子性,而是 讀取--修改--寫入,
如果過程中有兩個執行緒在跑,由於不恰當的執行時序出現不正確的結果稱為 “競態條件”
2.1 競態條件
public class A{ private B b = null; public B get(){ if(b == null) // thread1,thread2 同時判斷為null b = new B(); return b ; } }
2.3 複合操作
避免競態條件問題,就要a執行緒在修改變數時,b執行緒已經執行完,或者不執行。 對同一個狀態有A B 操作,一個執行緒執行A操作,另一個執行緒執行B操作,要麼是已經執行完,要不就是完全不執行,A B操作都是原子操作。 ++count 是複合操作,要以執行緒安全的方式去修復執行。 使用執行緒安全的物件進行記錄 public class A{ private final AtomicLong count = new AtomicLong(0); public long getCount(return count.get()); public void set(){ count.incrementAndGet(); } }
3.加鎖機制
3.1 內建鎖(同步程式碼塊 synchronized)
同步程式碼塊 synchronized(lock){ //訪問或修改由鎖保護的共享狀態 } 某個執行緒可以重如自己持有的鎖的程式碼中,每個鎖有一個計數器,所有者執行緒,計數器值=0 ,鎖未被持有,執行緒請求未被持有的鎖,jvm記下鎖持有者,計數器值+1, 同一個執行緒再次獲得鎖,計數值+1,執行緒退出,則-1. public class A{ public synchronized void do{ ... } } public class B extends A{ public synchronized void do{ super.do(); //同一個物件,可以多次重入加鎖的程式碼。 } }