java 高併發 之 鎖

2021-09-07 13:16:54 字數 3879 閱讀 8818

synchronized 是屬於宣告式加鎖,可以修飾乙個**塊、乙個方法、乙個類,乙個靜態方法。

// 修飾乙個**塊

public

void

test1

(int j)

- {}"

, j, i);}

}}

// 修飾乙個方法

public

synchronized

void

test2

(int j)

- {}"

, j, i);}

}

// 修飾乙個類

public

static

void

test1

(int j)

- {}"

, j, i);}

}}

// 修飾乙個靜態方法

public

static

synchronized

void

test2

(int j)

- {}"

, j, i);}

}

synchronized 是在jvm層面實現的,不但可以通過一些監控工具監控,而且出現系統異常了,jvm也會自動的解鎖,所以jvm會自動的做加鎖與解鎖操作,其用法對開發人員是完全透明的。

reentrantlock 是物件層面的鎖,需要手動的加鎖和解鎖。在加解鎖時機有了更靈活的選擇,並且提供了公平選擇和非公平選擇。

// 請求總數

public

static

int clienttotal =

5000

;// 同時併發執行的執行緒數

public

static

int threadtotal =

200;

public

static

int count =0;

private

final

static lock lock =

newreentrantlock()

;public

static

void

main

(string[

] args)

throws exception

catch

(exception e)

countdownlatch.

countdown()

;});

} countdownlatch.

await()

; executorservice.

shutdown()

; log.

info

("count:{}"

, count);}

private

static

void

add(

)finally

}

reentrantreadwritelock 實現了readwritelock介面,所有具備讀、寫鎖。

我們在對外提供api介面時,如果要保證執行緒安全,則需要對訪問物件的讀寫進行加鎖,對同乙個物件加鎖。

但是,如果都操作的併發遠遠高於寫操作,那麼會出現寫操作的執行緒一直處於等待(讀操作釋放鎖)狀態。

讀寫鎖雖然分離了讀和寫的功能,使得讀與讀之間可以完全併發,但是讀和寫之間依然是衝突的,讀鎖會完全阻塞寫鎖,它使用的依然是悲觀的鎖策略.如果有大量的讀執行緒,他也有可能引起寫執行緒的飢餓

private

final map

map =

newtreemap

<

>()

;private

final reentrantreadwritelock lock =

newreentrantreadwritelock()

;private

final lock readlock = lock.

readlock()

;private

final lock writelock = lock.

writelock()

;public data get

(string key)

finally

}public set

getallkeys()

finally

}public data put

(string key, data value)

finally

}class

data

stampedlock則是1.8後提供了一種樂觀的讀策略,這種樂觀策略的鎖非常類似於無鎖的操作,使得樂觀鎖完全不會阻塞寫執行緒;

內部實現是基於clh鎖的,clh鎖是一種自旋鎖,它保證沒有飢餓的發生,並且可以保證fifo(先進先出)的服務順序.

clh鎖的基本思想如下:鎖維護乙個等待執行緒佇列,所有申請鎖,但是沒有成功的執行緒都記錄在這個佇列中,每乙個節點代表乙個執行緒,儲存乙個標記位(locked).用與判斷當前執行緒是否已經釋放鎖;locked=true 沒有獲取到鎖,false 已經成功釋放了鎖

// 請求總數

public

static

int clienttotal =

5000

;// 同時併發執行的執行緒數

public

static

int threadtotal =

200;

public

static

int count =0;

private

final

static stampedlock lock =

newstampedlock()

;public

static

void

main

(string[

] args)

throws exception

catch

(exception e)

countdownlatch.

countdown()

;});

} countdownlatch.

await()

; executorservice.

shutdown()

; log.

info

("count:{}"

, count);}

private

static

void

add(

)finally

}

原始碼案例

class

point

finally

}//下面看看樂觀讀鎖案例

double

distancefromorigin()

finally

}return math.

sqrt

(currentx * currentx + currenty * currenty);}

//下面是悲觀讀鎖案例

void

moveifatorigin

(double newx,

double newy)

else}}

finally

}}

1、當併發量不是特別的時候,synchronized 是比較好的選擇,並且是不會引起死鎖的。

2、併發量不少,但執行緒數是可以預估的,reentrantlock是乙個比較好的實現。

Java併發之讀 寫鎖

讀取 沒有執行緒正在做寫操作且沒有執行緒請求寫操作 寫入 沒有執行緒正在做寫操作 這裡假設寫操作的優先順序比讀操作高 當乙個執行緒已經擁有寫鎖,才允許寫鎖重入 public class readwritelock writerequest writeaccesses writingthread ca...

Java併發之公平鎖

cpu在排程執行緒的時候,會在等待佇列裡隨機挑選乙個執行緒。由於隨機性,故不能保證執行緒先到先得 synchronized控制的鎖就是這種非公平鎖 這樣就會產生飢餓現象,即有些優先順序較低的執行緒可能永遠無法取得cpu的執行權,優先順序較高的執行緒會不斷搶占資源。於是,就有了公平鎖。公平鎖可以保證執...

高併發和鎖

面試被問到了這個問題,找了答案,記錄一下 假如有100w個使用者,搶一張票,除了負載均衡的辦法,怎麼支援高併發?修改字段 將庫存欄位number欄位設為unsigned,當庫存為0時,因為字段不能為負數,將會返回false 利用悲觀鎖 不適合高併發 悲觀鎖,也就是在修改資料的時候,採用鎖定狀態,排斥...