java 併發 ConcurrentHashMap 與 HashTable源碼分析總結

一、HashTable

源碼結構大致與HashTable相同,不同的地方是對數據進行讀取操作的方法都加上了synchronized


二、ConcurrentHashMap 則使用了 ReentrantLock 來解決併發問題。


三、java.util.concurrent.locks.ReentrantLock分析

其代碼結構大致如下:

public class ReentrantLock implements Lock{

private final Sync sync;

static abstract class Sync extends AbstractQueuedSynchronizer{

private volative int state; (AbstractQueuedSynchronizer中定義的變量)

final boolean nofairTryAcquire(int acquires);

protected final boolean tryRelease(int releases);

  ...

}

final static class NonfairSync extends Sync;

final static class FairSync extends Sync;

...

}

摘取其中兩段代碼:

 final boolean nofairTryAcquire(int acquires) {
134
            final Thread current = Thread.currentThread();
135
            int c = getState();
136
            if (c == 0) {
137
                if (compareAndSetState(0, acquires)) {  //使用Native的CAS方法來保證原子性
138
                    setExclusiveOwnerThread(current);
139
                    return true;
140
                }
141
            }
142
            else if (current == getExclusiveOwnerThread()) {
143
                int nextc = c + acquires;
144
                if (nextc < 0) // overflow
145
                    throw new Error("Maximum lock count exceeded");
146
                setState(nextc);
147
                return true;
148
            }
149
            return false;
150
        }

 protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
                     // getExclusiveOwnerThread()方法雖然讀取了共享變量,但是不需要使用CAS方法,這是因爲 getExclusiveOwnerThread()的Thread可能會改變,但是怎麼都不會改變 Thread.currentThread() != getExclusiveOwnerThread()的值,因爲currentThread在此行無法改變ExclusiveOwnerThread是否是自己。
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

  至於 fairTryAcquire 與 nofairTryAcquire的不同,主要在與獲取鎖的條件判斷上,除了

compareAndSetState(0,acquires)判斷state是否爲0外,多了一個條件 !hasQueuedPredecessors();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章