SoftReference(利用软引用写的一个简单HashMap)

软引用对象,在响应内存需要时,由垃圾回收器决定是否清除此对象。软引用对象最常用于实现内存敏感的缓存

软可到达对象的所有软引用都要保证在虚拟机抛出 OutOfMemoryError 之前已经被清除。

只要软引用的指示对象是强可到达对象,即正在实际使用的对象,就不会清除软引用

public class SoftHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {

    private static final int        DEFAULT_INITIAL_CAPACITY = 16;
    private static final int        MAXIMUM_CAPACITY         = 1 << 30;
    private Entry[]                 table;
    private final ReferenceQueue<K> queue                    = new ReferenceQueue<K>();
    private static final Object     NULL_KEY                 = new Object();
    private int                     size;

    public SoftHashMap() {
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
    }

    /**
     * @param key
     * @param value
     * @return
     */
    @SuppressWarnings("unchecked")
    public V put(K key, V value) {
        Entry[] tab = getTable();
        Entry temp;
        for (int j = 0; j < tab.length; j++) {
            temp = tab[j];
            if (temp == null) continue;
            V oldKey = (V) temp.getKey();
            if (key == oldKey) {
                temp.setValue(value);
                return (V) temp.getValue();
            }
            temp = null;
        }

        tab[size] = new Entry<K, V>(key, value, queue);
        if (++size >= table.length) resize(table.length << 1);
        return value;
    }

    /**
     * @param newCapacity
     */
    void resize(int newCapacity) {
        Entry[] newTable = new Entry[newCapacity];
        System.arraycopy(table, 0, newTable, 0, newTable.length);
        table = newTable;
    }

    /**
     * @param h
     * @param length
     * @return
     */
    static int indexFor(int h, int length) {
        return h & (length - 1);
    }

    /**
     * @param key
     * @return
     */
    private int hash(Object key) {
        return key.hashCode() & table.length;
    }

    /**
     * @return
     */
    private Entry[] getTable() {
        expungeStaleEntries();
        return table;
    }

    /**
     *
     */
    private void expungeStaleEntries() {
        Entry<K, V> e;
        while ((e = (Entry<K, V>) queue.poll()) != null) {
            e = null;
            size--;
        }
    }

    /**
     * @param key
     * @return
     */
    private static Object maskNull(Object key) {
        return (key == null ? NULL_KEY : key);
    }

    /**
     * @return
     */
    public Set<java.util.Map.Entry<K, V>> entrySet() {
        expungeStaleEntries();
        Set<Map.Entry<K, V>> entrys = new HashSet<Map.Entry<K, V>>();
        for (int i = 0; i < table.length; i++) {
            if (table[i] == null) continue;
            entrys.add(table[i]);
        }
        return entrys;
    }

 

  public String toString(){

            return entrySet().toString();

  }

 

 

    private static class Entry<K, V> extends SoftReference<K> implements Map.Entry<K, V> {

        private V value;

        public Entry(K k, V v, ReferenceQueue queue) {
            super(k, queue);
            this.value = v;
        }

        public K getKey() {
            return super.get();
        }

        public V getValue() {
            return value;
        }

        public V setValue(V value) {
            V oldvalue = value;
            this.value = value;
            return oldvalue;
        }

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

        public int hashCode() {
            Object k = getKey();
            Object v = getValue();
            return ((k == null ? 0 : k.hashCode()) ^ (v == null ? 0 : v.hashCode()));
        }

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

    public static void main(String[] args) throws Exception {
        SoftHashMap<Object, Object> softHashMap = new SoftHashMap<Object, Object>();
        Object key1 = new String("asdfasdf"); // 堆中的对象是可以被垃圾回收的,而栈中基本变量,引用变量,是在跳出所在的语句块时!
        // 基本类型变量或对象变量所在栈内存被系统自动释放!并且内存空间能够立即被释放!
        // Object key1 = "sadfasdf";

        Object value1 = "B";
        Object key2 = "D"; // 栈变量是不会被垃圾回收器收集的
        Object value2 = "B";
        Object key3 = "C";
        Object value3 = "B";

        softHashMap.put(key1, value1);
        softHashMap.put(key2, value2);
        softHashMap.put(key3, value3);
        softHashMap.put(key3, "asdfadfasd");
        key3 = null;
        // key2 = null;
        // key1 = null;
        System.gc();
        Thread.sleep(1000);
        Set<Map.Entry<Object, Object>> set = softHashMap.entrySet();
        for (Map.Entry<Object, Object> entry : set) {
            System.out.println("===" + entry.getValue());
        }

    }
}

你可能感兴趣的:(thread,虚拟机,J#)