執行緒的狀態主要有一下五種,分別是新建狀態,就緒狀態,執行狀態,阻塞狀態,消亡狀態等5種狀態
b).lock實現原理則是依賴於硬體,現代處理器都支援cas指令,所謂cas指令簡單的來說compare and set,cpu迴圈執行指令直到得到所期望的結果,換句話來說就是當變數真實值不等於當前執行緒呼叫時的值的時候(說明其他執行緒已經將這個值改變),就不會賦予變數新的值。這樣就保證了變數在多執行緒環境下的安全性。
然而,現實情況是當jdk版本高於1.6的時候,synchronized已經被做了cas的優化:具體是這樣的,當執行到synchronized**塊時,先對物件頭的鎖標誌位用lock cmpxchg的方式設定成「鎖住「狀態,釋放鎖時,在用lock cmpxchg的方式修改物件頭的鎖標誌位為」釋放「狀態,寫操作都立刻寫回主記憶體。jvm會進一步對synchronized時cas失敗的那些執行緒進行阻塞操作(呼叫作業系統的訊號量)(此段來摘自別處)。也就是先cas操作,不行的話繼而阻塞執行緒。
除此之外,系統環境,cpu架構,虛擬機器環境都會影響兩者的效能關係。
舉例如下
1).x86_64 cpu i7 4910mq @4.0ghz ,windows10 64bit,jdk1.8 hotspot 64bit虛擬機器環境
測試**
測試對某map物件高併發下的讀寫執行緒安全測試
測試對比有synchronized,readwritelock,concurrenthashmap,
public
class maptest
system.out.println("read-mapsize="+map.size());
if(count.decrementandget() == 0)
system.out.println("time="+ (system.currenttimemillis() - starttime +"ms"));}};
runnable writerun = new runnable()
system.out.println("write-mapsize="+map.size());
if(count.decrementandget() == 0)
system.out.println("time="+ (system.currenttimemillis() - starttime + "ms"));}};
public
void
run()}}
hashmap 用synchronized重寫
public
class
synchashmap
extends
hashmap
}@override
public
synchronized object put(object key, object value) }}
用讀寫鎖實現的map**類,有些粗糙,沒加try finally
public
private maporigin;
private readwritelock lock;
public
this.origin = origin;
lock = new reentrantreadwritelock();
}public
static
return
}@override
public
void
clear()
@override
public boolean containskey(object key)
@override
public boolean containsvalue(object value)
@override
public set> entryset()
@override
public v get(object key)
@override
public boolean isempty()
@override
public setkeyset()
@override
public v put(k key, v value)
@override
public
void
putall(map extends k, ? extends v> map)
@override
public v remove(object key)
@override
public
intsize()
@override
public collectionvalues()
}
synchronized與volatile關鍵字
volatile保證其他執行緒對這個變數操作時是立即可見的,即操作的是從記憶體中讀取的最新值 無法保證原子性 只能修飾變數 public class test public static void main string args throws exception start 控制台輸出 使用場景 ...
執行緒與併發 synchronized
多執行緒與高併發 當我們對乙個數字進行遞增操作時,如果兩個程式同時訪問,第乙個執行緒讀到count 0,並對其 1,在自己執行緒內部的記憶體裡還沒有寫回去的時候 第二個執行緒讀到的count也是0,並 1寫回去 但是程式明明對count進行了兩次 1操作,但結果還是1。那麼我們對這個遞增過程加上一把...
synchronized與鎖公升級
當乙個共享資源有可能被多個執行緒同時訪問並修改的時候,需要用鎖來保證資料的正確性。請看下圖 執行緒a和執行緒b分別往同乙個銀行賬戶裡面新增貨幣,a執行緒從記憶體中讀取 read 當前賬戶金額 0 到執行緒a的本地棧,進行 100的操作後,這時b執行緒也從記憶體中讀取當前金額 0 到執行緒b的本地棧,...