位置:org.springframework.util
�实现接口:java.util.concurrent.ConcurrentMap
继承类:java.util.AbstractMap
作用:支持空值或空键,并提供高并发下性能良好的键值存储调用
一、效果
ConcurrentReferenceHashMap是自spring3.2后增加的一个同步的软(虚)引用Map。关于软引用(SoftRefrence)和虚引用(WeakRefrence)可以参见另一篇文档:[Java] 垃圾回收机制与引用类型
@Testpublic void test1(){ConcurrentReferenceHashMap map = new ConcurrentReferenceHashMap(16, ConcurrentReferenceHashMap.ReferenceType.WEAK);map.put("key","val");System.out.println(map); // 输出:{key=val}System.gc();try {Thread.currentThread().sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(map); // 输出:{}}
二、API
@Nullableprivate V put(@Nullable final K key, @Nullable final V value, final boolean overwriteExisting) {return doTask(key, new Task<V>(TaskOption.RESTRUCTURE_BEFORE, TaskOption.RESIZE) {@Override@Nullableprotected V execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry, @Nullable Entries entries) {if (entry != null) {V oldValue = entry.getValue();if (overwriteExisting) {entry.setValue(value);}return oldValue;}Assert.state(entries != null, "No entries segment");entries.add(value);return null;}});}@Override@Nullablepublic V get(@Nullable Object key) {Entry<K, V> entry = getEntryIfAvailable(key);return (entry != null ? entry.getValue() : null);}@Nullableprivate Entry<K, V> getEntryIfAvailable(@Nullable Object key) {Reference<K, V> ref = getReference(key, Restructure.WHEN_NECESSARY);return (ref != null ? ref.get() : null);}@Nullableprotected final Reference<K, V> getReference(@Nullable Object key, Restructure restructure) {int hash = getHash(key);return getSegmentForHash(hash).getReference(key, hash, restructure);}@Nullablepublic Reference<K, V> getReference(@Nullable Object key, int hash, Restructure restructure) {if (restructure == Restructure.WHEN_NECESSARY) {restructureIfNecessary(false);}if (this.count == 0) {return null;}// Use a local copy to protect against other threads writingReference<K, V>[] references = this.references;int index = getIndex(hash, references);Reference<K, V> head = references[index];return findInChain(head, key, hash);}
三、总结
ConcurrentReferenceHashMap是基于Segment分段锁实现的,与JDK1.7的ConcurrentHashMap是一样的,与JDK1.8的ConcurrentHashMap是不一样的。
在JDK1.7中,ConcurrentHashMap将哈希表分成许多片段(segments),每个片段(table)都类似于HashMap,它有一个HashEntry数组,数组的每项又是HashEntry组成的链表。每个片段都是Segment类型的。Segment本质上是一个可重入的互斥锁,这样每个片段都有了一个锁,这就是“锁分段”。
在JDK1.8中,ConcurrentHashMap没有用“锁分段”来实现线程安全,而是使用CAS算法和synchronized来确保线程安全,但是底层segment并没有被删除的。
四、补充
无
