softReference 软引用

这个Employee类的构造方法中我们可以预见,如果每次需要查询一个雇员的信息。哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这是需要消耗很多时间的。下面是一个对Employee对象进行缓存的缓存器的定义:
 
01
import  java.lang.ref.ReferenceQueue;
02
import  java.lang.ref.SoftReference;
03
import  java.util.Hashtable;
04
 
05
public   class  EmployeeCache {
06
     static  private  EmployeeCache  cache ; // 一个 Cache实例
07
     private  Hashtable<String, EmployeeRef>  employeeRefs ; // 用于 Chche内容的存储
08
     private  ReferenceQueue<Employee>  q ; // 垃圾 Reference的队列
09
 
10
     // 继承 SoftReference,使得每一个实例都具有可识别的标识,
11
     // 并且该标识与其在 HashMap内的 key相同。
12
     private class EmployeeRef extends SoftReference<Employee> {
13
        private  String  _key  =  "" ;
14
 
15
        public  EmployeeRef(Employee em, ReferenceQueue<Employee> q) {
16
            super (em, q);
17
            _key  = em.getID();
18
       }
19
    }
20
 
21
     // 构建一个缓存器实例
22
     private  EmployeeCache() {
23
        employeeRefs  =  new  Hashtable<String,EmployeeRef>();
24
        q  =  new  ReferenceQueue<Employee>();
25
    }
26
 
27
     // 取得缓存器实例
28
     public   static synchronized EmployeeCache getInstance() {
29
       if  (cache == null){
30
            cache = new EmployeeCache();
31
       }
32
       return cache ;
33
    }
34
 
35
     // 以软引用的方式对一个 Employee对象的实例进行引用并保存该引用
36
     private   void  cacheEmployee(Employee em) {
37
       cleanCache(); // 清除垃圾引用
38
       EmployeeRef ref =  new  EmployeeRef(em,  q );
39
        employeeRefs .put(em.getID(), ref);
40
    }
41
 
42
     // 依据所指定的 ID号,重新获取相应 Employee对象的实例
43
     public  Employee getEmployee(String ID) {
44
       Employee em =  null ;
45
        // 缓存中是否有该 Employee实例的软引用,如果有,从软引用中取得。
46
        if  ( employeeRefs .containsKey(ID)) {
47
           EmployeeRef ref = (EmployeeRef)  employeeRefs .get(ID);
48
           em = (Employee) ref.get();
49
       }
50
        // 如果没有软引用,或者从软引用中得到的实例是 null,重新构建一个实例,
51
        // 并保存对这个新建实例的软引用
52
        if  (em ==  null ) {
53
           em =  new  Employee(ID);
54
           System. out .println( "Retrieve From EmployeeInfoCenter. ID="  + ID);
55
            this .cacheEmployee(em);
56
       }
57
        return  em;
58
    }
59
 
60
     // 清除那些所软引用的 Employee对象已经被回收的 EmployeeRef对象
61
     private   void  cleanCache() {
62
       EmployeeRef ref =  null ;
63
        while  ((ref = (EmployeeRef)  q .poll()) !=  null ) {
64
            employeeRefs .remove(ref. _key );
65
       }
66
    }
67
}

原文地址:https://www.cnblogs.com/drawwindows/p/3118338.html