JDK源码分析——WeakHashMap源码分析

M君 4月前 ⋅ 430 阅读

在介绍WeakHashMap之前,需要理清楚一个知识点:JVM中对象回收机制,在JVM中对象的回收的判断有一个比较重要的点是“引用机制”,为了应对业务中java的需求,jvm对引用又进行了更进一步的划分,不同的引用关系具有不同效果,使用不同的引用数据结构类型可以实现不同的业务需求,大致介绍如下文所示:

https://blog.csdn.net/m47838704/article/details/79548193

从上面的文字和文章的介绍我们可以看出,WeakHashMap是属于弱引用,也就是说存放在该数据结构中的信息会在jvm中内存不够的时候会被gc掉,所以可以被用于缓存一些不经常修改、访问频繁、但是又不是特别重要的信息。

那么疑问来了,WeakHashMap和我们经常使用的HashMap如何实现不一样的效果的呢?通过什么样的切入点去找到他们的不同点呢?

通过对Java语言和jvm的特性的了解,我们可以知道在java中所有的都是对象(显而易见),jvm的gc也是针对对象的,那么我们再进行更加深入的一点思考,WeakHashMap和HashMap里面存储的数据是不是也是对象呢,那两种数据结构的中的对象是否应该在内存不够的时候被gc,是不是意味着两种数据结构中的对象的引用类型不一样呢,那么也就意味着在WeakHashMap中的对象是弱引用的对象,通过下面的源码我们可以看出了相关区别。

从源码中我们可以看出在WeakHashMap中的节点继承了WeakReference,通过查看WeakReference类的描述可以看出了继承该类的对象的特性是:会在内存不够用的时候被gc,这也正符合WeakHashMap的需求。

WeakHashMap的Entry

/**
* The entries in this hash table extend WeakReference, using its main ref
* field as the key.
*/
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
V value;
final int hash;
Entry<K,V> next;

/**
* Creates new entry.
*/
Entry(Object key, V value,
ReferenceQueue<Object> queue,
int hash, Entry<K,V> next) {
super(key, queue);
this.value = value;
this.hash = hash;
this.next = next;
}

@SuppressWarnings("unchecked")
public K getKey() {
return (K) WeakHashMap.unmaskNull(get());
}

public V getValue() {
return value;
}

public V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}

public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
K k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
V v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}

public int hashCode() {
K k = getKey();
V v = getValue();
return Objects.hashCode(k) ^ Objects.hashCode(v);
}

public String toString() {
return getKey() + "=" + getValue();
}
}

HashMap中的Entry

static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;

Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}

public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }

public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}

public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}

public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}

 

 

 

 


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: