目前社區(qū)中有幾個(gè)應(yīng)用使用了類似Locker的代碼,基本上都是從消息系統(tǒng)引擎中提取出來的,的區(qū)別在于消息中使用的Locker中的id的類型為long,而id在作為鍵被put進(jìn)Map時(shí)被JVM自動(dòng)轉(zhuǎn)換成了Long,因此避免了 WeakHashMap中的鍵被值所引用。而如果使用String作為id則會(huì)因?yàn)镸ap中的值引用了自己的鍵,導(dǎo)致JVM無法根據(jù)鍵是否還被引用而清除 WeakHashMap中的entry??赏ㄟ^下面的測試代碼,清楚的觀察到結(jié)果。
public class Locker {
private static WeakHashMap lockerMap = 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); //問題代碼,導(dǎo)致了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
}
}
}
}
public class Locker {
private static 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); //問題代碼,導(dǎo)致了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
}
}
}
}

