这个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
}