JAVA四种引用方式(二)

2014-11-24 01:08:48 · 作者: · 浏览: 1
eference; import java.util.HashSet; import java.util.Set; /** * 测试引用 * @author TianYou */ public class TestReference { //创建一个引用队列 private static ReferenceQueue rq = new ReferenceQueue (); private static int size = 10; /** * 验证队列 */ public static void checkQueue(){ Reference ref = rq.poll(); if(null != ref) System.out.println("In queue: "+ref+" : "+ref.get()); } /** * 创建10个RefObject对象\以及10个软引用 */ public static void testSoftReference(){ System.out.println("--------执行软引用开始-------"); Set > sa = new HashSet >(); for(int i = 0; i < size; i++) { SoftReference ref= new SoftReference (new RefObject("SoftReference " + i), rq); System.out.println("Just created: " +ref.get()); sa.add(ref); } System.gc(); checkQueue(); System.out.println("--------执行软引用结束-------"); } /** * 创建10个Grocery对象以及10个弱引用 */ public static void testWeakReference(){ System.out.println("--------执行弱引用开始-------"); Set > wa = new HashSet >(); for(int i = 0; i < size; i++) { WeakReference ref=new WeakReference (new RefObject("WeakReference " + i), rq); System.out.println("Just created: " +ref.get()); wa.add(ref); } System.gc(); checkQueue(); System.out.println("--------执行软弱用结束-------"); } /** * 创建10个Grocery对象以及10个虚引用 */ public static void testPhantomReference(){ System.out.println("--------执行虚引用开始-------"); Set > pa = new HashSet >(); for(int i = 0; i < size; i++) { PhantomReference ref = new PhantomReference (new RefObject("PhantomReference " + i), rq); System.out.println("Just created: " +ref.get()); pa.add(ref); } System.gc(); checkQueue(); System.out.println("--------执行虚弱用结束-------"); } public static void main(String args[]){ testSoftReference(); testWeakReference(); testPhantomReference(); } } 在综合实例这里可以看到,三个引用依次都创建了10次,都包含了一个refobject对象,从打印结果可以明确看出,虚引用基本是形同虚设,它引用的对象随时会被垃圾回收器回收,具有弱引用的对象拥有的稍微长一点的生命周期,但垃圾回收器执行回操作时,依然有可能回被垃圾回收器回收,生命周期长的还是软引用。但在虚拟机内存不足的情况下依然会被回收,所以可出这些引用的方式真的不适合在线上使用,否则在极度容易出现鼓掌而在排查时很难检测出结果。
7、弱引用的WeakHashMap
弱引用的jar路径java.util.WeakHashMap。它是弱引用为键实现的哈希表的map。在weakHashMap表某个键不正常时,将会自动移出那个不正常的键。如果对持有强引用的key,它就会一直存在。同时它也支持null key和null value。更精确地说,对于一个给定的key,其映射的存在并不阻止垃圾回收器对该key的回收,这就使该key可以被终止的,key被终止,然后垃圾回收器回收。回收某个key时,其条目从映射中也会被有效地移除,因此,该类的行为与其他的 Map 实现有所不同
接下来也看看实例。
创建一个key对象

  public class Key {
String id;    
    public Key(String id) {  
        this.id = id;  
    }  
    public String toString() {  
        return id;  
    }  
    public int hashCode() {  
        return id.hashCode();  
    }  
    public boolean equals(Object r) {  
        return (r instanceof Key) && id.equals(((Key) r).id);  
    }  
    public void finalize() {  
        System.out.println("Finalizing Key " + id);  
    }
}
创建一个value对象
public class Value {
String id;  
    public Value(String id) {  
        this.id = id;  
    }  
    public String toString() {  
        return id;  
    }  
    public void finalize() {  
        System.out.println("Finalizing Value " + id);  
    }  
}

测试对象
     import java.util.WeakHashMap;
public class MapCache {
public static void main(String[] args) throws Exception {  
        int size = 10000;
        Key[] keys = new Key[size]; 
        WeakHashMap
  
    whm = new WeakHashMap
   
    (); for (int i = 0; i < size; i++) { Key k = new Key(Integer.toString(i)); Value v = new Value(Integer.toString(i)); if (i % 5 == 0) keys[i] = k; // 使Key对象持有强引用 whm.put(k, v); // 使Key对象持有弱引用 } // 催促垃圾回收器工作 System.gc(); // 把CPU让给垃圾回收器线程 Thread.sleep(8000); } } 运行结果看出来 整出5的对象持有强引用被保留了下来