synchronized與lock之間的效能比較

2021-08-14 14:09:57 字數 2537 閱讀 8447

執行緒的狀態主要有一下五種,分別是新建狀態,就緒狀態,執行狀態,阻塞狀態,消亡狀態等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的本地棧,...