日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql的锁是公平的么_lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现...

發布時間:2023/12/3 数据库 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql的锁是公平的么_lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ReentrantLock的實現是基于其內部類FairSync(公平鎖)和NonFairSync(非公平鎖)實現的。 其可重入性是基于Thread.currentThread()實現的: 如果當前線程已經獲得了執行序列中的鎖, 那執行序列之后的所有方法都可以獲得這個鎖。

公平鎖:

公平和非公平鎖的隊列都基于鎖內部維護的一個雙向鏈表,表結點Node的值就是每一個請求當前鎖的線程。公平鎖則在于每次都是依次從隊首取值。

鎖的實現方式是基于如下幾點:

表結點Node和狀態state的volatile關鍵字。

sum.misc.Unsafe.compareAndSet的原子操作(見附錄)。

非公平鎖:

在等待鎖的過程中, 如果有任意新的線程妄圖獲取鎖,都是有很大的幾率直接獲取到鎖的。

ReentrantLock鎖都不會使得線程中斷,除非開發者自己設置了中斷位。

ReentrantLock獲取鎖里面有看似自旋的代碼,但是它不是自旋鎖。

ReentrantLock公平與非公平鎖都是屬于排它鎖。

公平鎖和非公平鎖在說的獲取上都使用到了 volatile 關鍵字修飾的state字段, 這是保證多線程環境下鎖的獲取與否的核心。

但是當并發情況下多個線程都讀取到 state == 0時,則必須用到CAS技術,一門CPU的原子鎖技術,可通過CPU對共享變量加鎖的形式,實現數據變更的原子操作。

volatile 和 CAS的結合是并發搶占的關鍵。

公平鎖的實現機理在于每次有線程來搶占鎖的時候,都會檢查一遍有沒有等待隊列,如果有, 當前線程會執行如下步驟:

/**

* Fair version of tryAcquire. Don't grant access unless

* recursive call or no waiters or is first.

*/

protected final boolean tryAcquire(int acquires) {

final Thread current = Thread.currentThread();

int c = getState();

if (c == 0) {

if (!hasQueuedPredecessors() &&

compareAndSetState(0, acquires)) {

setExclusiveOwnerThread(current);

return true;

}

}

else if (current == getExclusiveOwnerThread()) {

int nextc = c + acquires;

if (nextc < 0)

throw new Error("Maximum lock count exceeded");

setState(nextc);

return true;

}

return false;

}

其中hasQueuedPredecessors是用于檢查是否有等待隊列的。

非公平鎖在實現的時候多次強調隨機搶占:

/**

* Performs lock. Try immediate barge, backing up to normal

* acquire on failure.

*/

final void lock() {

if (compareAndSetState(0, 1))

setExclusiveOwnerThread(Thread.currentThread());

else

acquire(1);

}

當當前擁有鎖的線程釋放鎖之后, 且非公平鎖無線程搶占,就開始線程喚醒的流程。

通過tryRelease釋放鎖成功,調用LockSupport.unpark(s.thread);?終止線程阻塞

private void unparkSuccessor(Node node) {

// 強行回寫將被喚醒線程的狀態

int ws = node.waitStatus;

if (ws < 0)

compareAndSetWaitStatus(node, ws, 0);

Node s = node.next;

// s為h的下一個Node, 一般情況下都是非Null的

if (s == null || s.waitStatus > 0) {

s = null;

// 否則按照FIFO原則尋找最先入隊列的并且沒有被Cancel的Node

for (Node t = tail; t != null && t != node; t = t.prev)

if (t.waitStatus <= 0)

s = t;

}

// 再喚醒它

if (s != null)

LockSupport.unpark(s.thread);

}

非公平鎖性能高于公平鎖性能的原因:

在恢復一個被掛起的線程與該線程真正運行之間存在著嚴重的延遲。

假設線程A持有一個鎖,并且線程B請求這個鎖。由于鎖被A持有,因此B將被掛起。當A釋放鎖時,B將被喚醒,因此B會再次嘗試獲取這個鎖。與此同時,如果線程C也請求這個鎖,那么C很可能會在B被完全喚醒之前獲得、使用以及釋放這個鎖。這樣就是一種雙贏的局面:B獲得鎖的時刻并沒有推遲,C更早的獲得了鎖,并且吞吐量也提高了。

當持有鎖的時間相對較長或者請求鎖的平均時間間隔較長,應該使用公平鎖。在這些情況下,插隊帶來的吞吐量提升(當鎖處于可用狀態時,線程卻還處于被喚醒的過程中)可能不會出現。

總結

以上是生活随笔為你收集整理的mysql的锁是公平的么_lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。