ConcurrentHashMap 原理解析

ConcurrentHashMap 原理解析

ConcurrentHashMap.class

其他配套信息,初始化构造函数

 

内部类  static class Segment<K,V> extends ReentrantReadWriteLock implements Serializable 

所有增删改

 

 

 

1,初始化: 构造函数创建segements空间,并且对每个segement创建table

2,操作:操作时根据key找到segement(内部类),

3,对于put操作等,引入就锁lock(读写锁),先根据key进行hash算法找到segement,然后在桶中找到这个桶的table中的第一个,

再根据这第一个遍历,找到了就覆盖返回旧值,没找到就新增

 (由于这个table[index]存的是entry这是一个单链表结构,这样获取第一个(table[index])之后可以马上对其遍历)

 transient volatile HashEntry<K,V>[] table;//忽略这个成员变量序列化

 

 

//由于这个table是内部类,每new Segment一个桶就有一个table变量在里面,由于就是属于这个内部类的所以类似threadlocal效果,

//对于大类将有一个内部类,那么大类操作这个内部类就相当于threadlocal变量

 

  public ConcurrentHashMap(int initialCapacity,

                             float loadFactor, int concurrencyLevel) {

        if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)

            throw new IllegalArgumentException();

 

        if (concurrencyLevel > MAX_SEGMENTS)

            concurrencyLevel = MAX_SEGMENTS;

 

        // Find power-of-two sizes best matching arguments

        int sshift = 0;

        int ssize = 1;

        while (ssize < concurrencyLevel) {

            ++sshift;

            ssize <<= 1;

        }

        segmentShift = 32 - sshift;

        segmentMask = ssize - 1;

        this.segments = Segment.newArray(ssize);

 

        if (initialCapacity > MAXIMUM_CAPACITY)

            initialCapacity = MAXIMUM_CAPACITY;

        int c = initialCapacity / ssize;

        if (c * ssize < initialCapacity)

            ++c;

        int cap = 1;

        while (cap < c)

            cap <<= 1;

 

        for (int i = 0; i < this.segments.length; ++i)

            this.segments[i] = createSegment(cap, loadFactor);

    }

 

 protected Segment<K, V> createSegment(int initialCapacity, float lf) {

        return new Segment<K, V>(initialCapacity, lf);

    }

 

Segment(int initialCapacity, float lf) {

            loadFactor = lf;

            setTable(HashEntry.<K,V>newArray(initialCapacity));

        }

 

 

 

 void setTable(HashEntry<K,V>[] newTable) {

            threshold = (int)(newTable.length * loadFactor);

            table = newTable;

        }

 

 

 

 

  public V put(K key, V value) {

        if (value == null)

            throw new NullPointerException();

        int hash = hash(key.hashCode());

        return segmentFor(hash).put(key, hash, value, false);

    }

 

 

 

      public V put(K key, V value) {

        if (value == null)

            throw new NullPointerException();

        int hash = hash(key.hashCode());

        return segmentFor(hash).put(key, hash, value, false);

    }

    

    

    

    V put(K key, int hash, V value, boolean onlyIfAbsent) {

            writeLock().lock();

            try {

                int c = count;

                if (c++ > threshold) // ensure capacity

                    rehash();

                HashEntry<K,V>[] tab = table;

                int index = hash & (tab.length - 1);

                HashEntry<K,V> first = tab[index];

                HashEntry<K,V> e = first;

                while (e != null && (e.hash != hash || !key.equals(e.key)))

                    e = e.next;

 

                V oldValue;

                if (e != null) {

                    oldValue = e.value;

                    if (!onlyIfAbsent)

                        e.value = value;

                }

                else {

                    oldValue = null;

                    ++modCount;

                    tab[index] = new HashEntry<K,V>(key, hash, first, value);

                    count = c; // write-volatile

                }

                return oldValue;

            } finally {

                writeLock().unlock();

            }

        }

 

猜你喜欢

转载自yuhuiblog6338999322098842.iteye.com/blog/2374084