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的对象持有强引用被保留了下来