1. 程式人生 > >WeakHashMap 用法和原理

WeakHashMap 用法和原理

在《Effective Java》一書中第六條,消除陳舊物件時,提到了weakHashMap,看了下還是適用的,即在我們使用短時間內就過期的快取時最好使用weakHashMap,它包含了一個自動呼叫的方法expungeStaleEntries,這樣就會在值被引用後直接執行這個隱含的方法,將不用的鍵清除掉。

 測試了一下

Java程式碼  收藏程式碼
  1. package com.alibaba.itbu.job.billing;  
  2. import java.util.Map;  
  3. import java.util.WeakHashMap;  
  4. public class WeakHashMapTest {  
  5.     static Map wMap = new WeakHashMap();  
  6.     public static void init(){  
  7.         wMap.put("1""ding");  
  8.         wMap.put("2""job");  
  9.     }  
  10.     public static void testWeakHashMap(){  
  11.         System.out.println("first get:"+wMap.get("1"));  
  12.         try {  
  13.             Thread.sleep(5000);  
  14.         } catch
     (InterruptedException e) {  
  15.             // TODO Auto-generated catch block  
  16.             e.printStackTrace();  
  17.         }  
  18.         System.out.println("next get:"+wMap.get("1"));  
  19.     }  
  20.     public static void main(String[] args) {  
  21.         testWeakHashMap();  
  22.     }  
  23. }  

上面例子, 第一次執行時要初始化,然後在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程式碼  收藏程式碼
  1. private void expungeStaleEntries() {  
  2.     Entry<K,V> e;  
  3.         while ( (e = (Entry<K,V>) queue.poll()) != null) {  
  4.             int h = e.hash;  
  5.             int i = indexFor(h, table.length);  
  6.             Entry<K,V> prev = table[i];  
  7.             Entry<K,V> p = prev;  
  8.             while (p != null) {  
  9.                 Entry<K,V> next = p.next;  
  10.                 if (p == e) {  
  11.                     if (prev == e)  
  12.                         table[i] = next;  
  13.                     else  
  14.                         prev.next = next;  
  15.                     e.next = null;  // Help GC  
  16.                     e.value = null//  "   "  
  17.                     size--;  
  18.                     break;  
  19.                 }  
  20.                 prev = p;  
  21.                 p = next;  
  22.             }  
  23.         }  
  24.     }  

就是使用了連結串列,找到這個hash值  將這個hash值移除 size減少

轉自:http://dingjob.iteye.com/blog/668670