使用者空間的讀寫鎖的實作已經有很多了,評價一個實作的好壞的标準也不一樣,本文的實作是一個抄襲,也可以說是一個改進,抄襲誰的呢?當然是我最熟悉的linux核心的了,linux核心的讀寫鎖的實作非常的藝術,都知道讀寫鎖是一種不對稱的鎖,讀和寫當然是不對稱的,在實作上可以展現為代碼上的不對稱和資料的不對稱,然而這兩種不對稱卻從來沒有得到人們的關注,我在一本講MySQL源代碼的書上看到了一段描述,主要是講為何MySQL不用讀寫鎖而用互斥鎖,作者認為是讀寫鎖實作起來太複雜,會多浪費好幾個cpu周期,實際上得到的優惠還不足以彌補cpu周期浪費。從這一段描述中可以看得出的是,MySQL的作者将讀寫鎖實作中不對稱設想成了代碼的不對稱,這樣才會得到浪費cpu周期的結論,如果考慮資料的不對稱,哪個資料對于cpu來講是無所謂的,隻是代碼加工的原料而已。linux核心巧妙的使用了資料的不對稱性來實作讀寫鎖,這個就自己看代碼吧。
近期我在一篇blog上看到了一個讀寫鎖的實作,語言是java,用什麼語言似乎不是那麼重要,關鍵是如何實作的,首先看一下這個代碼:
public class ReadWriteLock {
private boolean isRead;
private boolean isWrite;
public synchronized void readLock() {
while (isWrite) {
try {
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
isRead=true;
public synchronized void readUnlock() {
isRead=false;
notifyAll();
public synchronized void writeLock() {
while(isRead) {
} catch(InterruptedException ex) {
while(isWrite) {
try{
isWrite=true;
public synchronized void writeUnlock() {
isWrite=false;
看完了給人的感覺就是簡單之極,很容易了解,面試的時候肯定能過關,但是明顯read和write的lock代碼量不同,寫鎖的代碼量幾乎是讀鎖的兩倍,如果看了下面的實作,如果下面實作的作者和上面的作者一起參加了一場面試,我估計上面的哥們就危險了,當然同時被錄取更好,就怕是二選一的情況。看完上面的實作以後我估計MySQL的作者擔心是有道理的,他肯定也把讀寫鎖的實作想成了上面的樣子,下面看看仿linux核心的實作:
int count = 200;
int delta = count; //讀鎖的共享量,當然可以更大些,200000都可以。
doLockUnlock(1, 1);
doLockUnlock(delta, 0);
doLockUnlock(delta, 1);
public synchronized void doLockUnlock(int delta, int op) {
if (op) {
while(count-delta <=0) {
count -= delta;
} else {
count += delta;
最後說一下,上面的仿linux核心的實作的作者就是我自己。
本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1274104