StampedLock的理解和使用

2022-07-04 15:27:08 字數 2426 閱讀 7029

stampedlock是為了優化可重入讀寫鎖效能的乙個鎖實現工具,jdk8開始引入

相比於普通的reentranreadwritelock主要多了一種樂觀讀的功能

在api上增加了stamp的入參和返回值

不支援重入

我看了上面的介紹仍然對stampedlock一頭霧水,下面我們來揭開stampedlock神秘的面紗

下面是stampedlock的悲觀讀、寫鎖的實現

static executorservice service = executors.newfixedthreadpool(10

);static stampedlock lock = new

stampedlock();

static

long milli = 5000

;static

int count = 0;

private static long writelock()

private static void readlock()  catch (interruptedexception e) 

} finally

system.out.println("readlock==" + currentcount); //顯示最新的變數值

});try catch (interruptedexception e)

}

測試一下效果:

public

static

void

main(string args)

輸出結果:

資料寫入完成

5064

readlock==0

寫被讀鎖阻塞了5秒

我們新增了乙個樂觀讀的方法,這個方法仍然模擬讀取延遲5秒,樂觀讀實現需要參考下面的程式設計模式(獲取樂觀鎖、校驗是否進入寫模式)

private static void optimisticread()  catch (interruptedexception e) 

if (!lock.validate(stamp)) finally

}//走到這裡,說明count還沒有被寫,那麼可以不用加讀鎖,減少了讀鎖的開銷

system.out.println("optimisticread==" + currentcount); //顯示最新的變數值

});try catch (interruptedexception e)

}

測試一下效果:

public

static

void

main(string args)

輸出結果:

資料寫入完成

553(中間等了大概5秒)

optimisticread==1

寫沒有被被讀鎖阻塞,樂觀讀最終走了悲觀讀讀取了最新值

public

class

stampedlockxingnengtest );

}service.invokeall(list);

long end =system.currenttimemillis();

system.out.println(end-begin);

//樂觀95 91 102 98 92

//悲觀265 253 293 265 287

}

private

static

void readlock()

catch

(interruptedexception e)

finally

}private

static

void

optimisticread()

catch

(interruptedexception e)

finally}}

}

針對以上**我分別對樂觀讀鎖和悲觀讀鎖測試了5次,每次10000併發並且每次回sleep10ms,測試結果如下

樂觀(ms)95 91 102 98 92

悲觀(ms)265 253 293 265 287

樂觀讀鎖整體效能大概是悲觀讀鎖3倍

可以看到相比直接用悲觀讀鎖,樂觀讀鎖可以:

1、進入悲觀讀鎖前先看下有沒有進入寫模式(說白了就是有沒有已經獲取了悲觀寫鎖)

2、如果其他執行緒已經獲取了悲觀寫鎖,那麼就只能老老實實的獲取悲觀讀鎖(這種情況相當於退化成了讀寫鎖)

3、如果其他執行緒沒有獲取悲觀寫鎖,那麼就不用獲取悲觀讀鎖了,減少了一次獲取悲觀讀鎖的消耗和避免了因為讀鎖導致寫鎖阻塞的問題,直接返回讀的資料即可(必須再tryoptimisticread和validate之間獲取好資料,否則資料可能會不一致了,試想如果過了validate再獲取資料,這時資料可能被修改並且讀操作也沒有任何保護措施)

比讀寫鎖更快的StampedLock

readwritelock支援兩種模式 讀鎖 寫鎖 stampedlock支援三種模式 悲觀讀鎖 寫鎖 樂觀讀 stampedlock的悲觀讀鎖和寫鎖 與 readwritelock的讀鎖和寫鎖 語義相似,允許多個執行緒獲取悲觀讀鎖,只允許乙個執行緒獲取寫鎖,寫鎖和悲觀讀鎖是互斥的。不同的是stam...

的理解和使用

本文出自 在傳統 jsp 中,想要實現頁面布局管理比較麻煩,為了解決在 jsp 中布局的問題,出現了很多開源軟體,比如 apache tiles 和 sitemesh 就是其中比較優秀的。但是使用開源軟體實現布局或多或少會產生一些效能問題,有沒有辦法在不依賴第三方開源軟體的情況下,使用 jsp 本身...

和equals的理解

equals方法是object類提供的乙個例項方法,所以所有的引用變數都可以呼叫該方法來判斷所指向的物件是否相等,該方法判斷的標準和 的判斷標準沒有任何區別都是用來比較需要比較物件的位址是否相同。但是為什麼有了 還要寫乙個equals方法呢?之所以這這樣多此一舉是因為可以讓子類重寫equals方法,...