LinkedHashMap

LinkedHashMap

这是一个继承自HashMap的类,在类说明中,这是一个非同步的,不能在多线程环境下使用,否则要自己实现同步.有两种模式,一种是元素访问的次数排序,一种是插入的时间排序
Linked内部含有一个private transient Entry header;来记录元素插入的顺序或者是元素被访问的顺序。
正如 LinkedHashMap的文档所说,LinkedHashMap简直就是为了实现LRU Cache(Least Recently Used)而编写的。正因为如此,在oscache或者是ehcache都使用到了LinkedHashMap。(oscache中是否使用LRU是可以配置的)
那么,这是如何实现的呢,见源码如下:
public V get(Object key) {
        Entry<K,V> e = (Entry<K,V>)getEntry(key);
        if (e == null)
            return null;
        e.recordAccess(this);
        return e.value;
}


这是取值的代码,请看得到实体的代码:
final Entry<K,V> getEntry(Object key) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
 }


完全是从hashMap中得到实体对象,根据key.
这里调用了recordAccess方法,然后再返回value.请看:
void recordAccess(HashMap<K,V> m) {
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) {
                lm.modCount++;
                remove();
                addBefore(lm.header);
            }
}


如果accessOrder实true,那是是访问排序,如果为false则为插入排序。
transient volatile int modCount;
这个参数可以用来标识修改次数,也可以用来标识访问次数

private void remove() {
            before.after = after;
            after.before = before;
}



从列表上移除该对象.
 private void addBefore(Entry<K,V> existingEntry) {
            after  = existingEntry;
            before = existingEntry.before;
            before.after = this;
            after.before = this;
}


把这个对象添加到第一个.

你可能感兴趣的:(java,多线程,cache)