WeakReference & ReferenceQueue实际使用的例子

实现Java对象的高速缓存

java bean对象:

package com.example.leakcanary.test;

public class Employee {

    private String id;

    private String name;

    public Employee(String id) {
        this.id = id;
        this.name = String.valueOf(System.currentTimeMillis());

    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

cache:

package com.example.leakcanary.test;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class EmployeeCache {
    //单例
    private static volatile EmployeeCache cache;

    //容器
    private Map<String, WeakEmployee> referent;

    //引用队列当SoftEmployee对象中的目标对象被销毁后 会自定把SoftEmployee对象加入到该序列中
    //这样就可以及时的清掉没有目标对象的SoftEmployee
    private ReferenceQueue<Employee> queue;

    //同步锁
    private static Object lock = new Object();

    //继承SoftReference,实现对对象的软引用
    //这个类所引用的目标对象会在JVM内存不足时自动回收
    private static class WeakEmployee extends WeakReference<Employee> {

        private String key;

        public String getKey() {
            return key;
        }

        public WeakEmployee(Employee referent, ReferenceQueue<Employee> queue) {
            super(referent, queue);
            this.key = referent.getId();
        }

    }

    public synchronized Employee getEmployee(String id) {
        Employee e = null;
        if(referent.containsKey(id)) {
            e = referent.get(id).get();
        }
        if(e == null) {
            e = new Employee(id);
            cacheEmployee(e);
        }
        return e;
    }

    //缓存对象
    private void cacheEmployee(Employee e) {
        cleanCache();// 清除垃圾引用
        WeakEmployee ref = new WeakEmployee(e, queue);
        referent.put(e.getId(), ref);
    }

    //私有化构造参数
    private EmployeeCache() {
        this.referent = Collections.synchronizedMap(new HashMap<String, WeakEmployee>());
        this.queue = new ReferenceQueue<>();
    }

    //获得实例
    public static EmployeeCache getInstance() {
        if(cache == null) {
            synchronized (lock) {
                if(cache == null) {
                    cache = new EmployeeCache();
                }
            }
        }
        return cache;
    }

    //将SoftEmployee中目标元素为空的对象清除
    private void cleanCache() {
        WeakEmployee se = null;
        while((se = (WeakEmployee)queue.poll()) != null) {
            referent.remove(se.getKey());
            System.out.println("对象ID : " + se.getKey() + "已经被JVM回收");
        }
    }

    public int getSize() {
        return referent.size();
    }

    //清除缓存
    public void clearCache() {
        cleanCache();
        referent.clear();
    }
}

测试:

package com.example.leakcanary.test;

public class CacheTest {
    public static void main(String[] args) throws InterruptedException {
        EmployeeCache cache = EmployeeCache.getInstance();
        for (int i = 0; i < 600000; i++) {
            cache.getEmployee(String.valueOf(i));
        }
    }
}

results matching ""

    No results matching ""