WeakHashMap 用法和原理
阿新 • • 發佈:2019-01-10
在《Effective Java》一書中第六條,消除陳舊物件時,提到了weakHashMap,看了下還是適用的,即在我們使用短時間內就過期的快取時最好使用weakHashMap,它包含了一個自動呼叫的方法expungeStaleEntries,這樣就會在值被引用後直接執行這個隱含的方法,將不用的鍵清除掉。
測試了一下
Java程式碼- package com.alibaba.itbu.job.billing;
- import java.util.Map;
- import java.util.WeakHashMap;
-
public class WeakHashMapTest {
- static Map wMap = new WeakHashMap();
- public static void init(){
- wMap.put("1", "ding");
- wMap.put("2", "job");
- }
- public static void testWeakHashMap(){
- System.out.println("first get:"+wMap.get("1"));
- try {
- Thread.sleep(5000);
-
} catch
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("next get:"+wMap.get("1"));
- }
- public static void main(String[] args) {
- testWeakHashMap();
- }
- }
上面例子, 第一次執行時要初始化,然後在5s內是不會清除的,大概在10幾秒時會清除
第一次執行
first get:ding
next get:ding
過一會再執行:
first get:null
next get:null
這時候已經被清除
同樣,沒有呼叫任何賦值方法的情況下,在一段時間後 size 方法也可能返回較小的值,對於 isEmpty 方法,返回 false,然後返回 true,對於給定的鍵,containsKey 方法返回 true 然後返回 false,對於給定的鍵,get 方法返回一個值,但接著返回 null,對於以前出現在對映中的鍵,put 方法返回 null,而 remove 方法返回 false,對於鍵集、值集、項集進行的檢查,生成的元素數量越來越少。
注意:WeakHashMap並不是你啥也幹他就能自動釋放內部不用的物件的,而是在你訪問它的內容的時候釋放內部不用的物件。這兩句話看似區別不大,但是有時候一個小小的區別就會要了命的。就是說你只put 了壓根沒有get過,這個值是永遠都存在的
我們也可以看下這個移除鍵值的實現
Java程式碼- private void expungeStaleEntries() {
- Entry<K,V> e;
- while ( (e = (Entry<K,V>) queue.poll()) != null) {
- int h = e.hash;
- int i = indexFor(h, table.length);
- Entry<K,V> prev = table[i];
- Entry<K,V> p = prev;
- while (p != null) {
- Entry<K,V> next = p.next;
- if (p == e) {
- if (prev == e)
- table[i] = next;
- else
- prev.next = next;
- e.next = null; // Help GC
- e.value = null; // " "
- size--;
- break;
- }
- prev = p;
- p = next;
- }
- }
- }
就是使用了連結串列,找到這個hash值 將這個hash值移除 size減少
轉自:http://dingjob.iteye.com/blog/668670