[宝贝交友不慎父母需淡定指导]没有哪位父母,忍心并甘心看到自己努力培养的孩子被他的“坏”朋友而带消极影响。但是,同样不能否认的是,孩子在成长过程当中,会遇到形形色色的朋友。那么显然,孩子与谁交往、与谁...+阅读
目前社区中有几个应用使用了类似Locker的代码,基本上都是从消息系统引擎中提取出来的,的区别在于消息中使用的Locker中的id的类型为long,而id在作为键被put进Map时被JVM自动转换成了Long,因此避免了 WeakHashMap中的键被值所引用。而如果使用String作为id则会因为Map中的值引用了自己的键,导致JVM无法根据键是否还被引用而清除 WeakHashMap中的entry。可通过下面的测试代码,清楚的观察到结果。
public class Locker {
private static WeakHashMaplockerMap = new WeakHashMap();
private final String id;
private Locker(String id) {
this.id= id;
}
public synchronized static Locker acquire(String id) {
Locker locker = lockerMap.get(key);
if (locker == null) {
locker = new Locker(id);
lockerMap.put(id, locker); 问题代码,导致了entry.key == entry.value.id
lockerMap.put(new String(id), locker); 这是一种修改方式,保证了WeakHashMap中的key,没有被value直接或间接所引用
}
return locker;
}
public String getId() {
return this.id;
}
public static int getSize() {
return lockerMap.size();
}
}
public class LockerTest extends TestCase {
public void testLocker() {
for (int i = 0; i< 10000000; i++) {
Locker.acquire("abc" + i);
if (i % 10000 == 0) {
System.gc();
System.out.println(Locker.getSize()); 输出垃圾回收后的Map的Size
}
}
}
}