每天一个java类之ConcurrentHashMap

来源:互联网 发布:seo整站优化多少费用 编辑:程序博客网 时间:2024/05/17 22:21


public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>,Serializable{


private static final long serialVersionUID = L;

static final int DEFAULT_INITIAL_CAPACITY = 16;

static final float DEFAULT_LOAD_FACTOR = 0.75f;

static final int DEFAULT_CONCURRENCY_LEVEL = 16;

static final int MAXIMUM_CAPACITY = 1 << 30;

static final int MIN_SEGMENT_TABLE_CAPACITY = 2;

static final int MAX_SEGMENTS = 1 << 16;

static final int RETRIES_BEFORE_LOCK = 2;

// hold values which can't be initialized until after VM is booted.


private static class Holder{

}

private transient final int hashSeed = randomHashSeed(this);

private static int randomHashSeed(ConcurrentHashMap instance){

if(sun.misc.VM.isBooted() && Holder.ALTERNATE_HASHING){

return sun.misc.Hashing.randomHashSeed(instance));

}

return 0;


final  int segmentMask;

final int segmentShift;

final Segment<K,V>[] segments;

transient   Set<K> keySet;

transient Set<Map.Entry<K,V>> entrySet;

transient Collection<V> values;

static final class HashEntry<K,V>{

final int hash;

final K key;

volatile V value;

volatile  HashEntry <K,V> next;

HashEntry(int hash, K key , V value, HashEntry<K,V> next){

this.hash = hash;

this.key = key;

this.value = value;

this.next = next;


}


final vold setNext(HashEntry<K,V> n){

UNSAFE.putOrderedObject(this,nextOffset,n);

}


static final sun.misc.Unsafe UNSAFE;

static final long nextOffset;

static{

try{

UNSAFE = sun.misc.Unsafe.getUnsafe();

Class k = HashEntry.class

nextOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("next"));

}catch(Exception e ){

throw new Error(e);

}

}

}



static final <K, V> HashEntry<K,V> entryAt(HashEntry<K,V> [] tab , int i){

return (tab == null) ? null : (HashEntry<K,V>) UNSAFE.getObjectVolatile(tab,((long) i << TSHIFT) + TBASE);

}


static final <K,V> void setEntryAt(HashEntry<K,V> [] tab , int i, HashEntry<K,V> e){

UNSAFE.putOrderedObject(tab,((long) i << TSHIFT) + TBASE , e);

}


private int hash(Object k){

int h = hashSeed;

if( (0 != h) && (k instanceof String) )

return sun.misc.Hashing.stringHash32((String) k); 

h ^= k.hashCode();

h += (h<<15) ^ 0xffffcd7d;

h ^= ( h >>> 10);

h += (h << 3);

h ^= (h >>> 6);

h += (h<<2) + (h << 14);

return h ^ (h>>>16);

}


//Segment是specialized hash map,维护的是a table of entry lists that are always kept in a consistent state.

//因此可以直接读,要不需要锁

static final class Segment <K,V> extends ReentrantLock implements Serializable{
<span style="white-space:pre"></span>private static final long serialVersionUID = ;
<span style="white-space:pre"></span>static final int MAX_SCAN_RETRIES = Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
<span style="white-space:pre"></span>transient volatile HashEntry<K,V> []table;<span style="white-space:pre"></span>transient<span style="white-space:pre"></span>int count;<span style="white-space:pre"></span>transient int modCount;
<span style="white-space:pre"></span>transient int threshold;
<span style="white-space:pre"></span>final float loadFactor;
<span style="white-space:pre"></span>Segment(float fl, int threshold, HashEntry<K,V> []tab){
<span style="white-space:pre"></span>this.loadFactor = lf;
<span style="white-space:pre"></span>this.threshold = threshold;
<span style="white-space:pre"></span>this.table = tab;
<span style="white-space:pre"></span>} 
<span style="white-space:pre"></span>final V put (K key  , int hash, V value, boolean onlyIfAbsent){
<span style="white-space:pre"></span>HashEntry<K,V> node = tryLock()?null : scanAndLockForPut(key,hash,value);
<span style="white-space:pre"></span>
<span style="white-space:pre"></span>
<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}


TO be continued


}

0 0
原创粉丝点击