不解释,直接上代码,千言万语顶不住一行代码。
package com.apkkids.javalanguage;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
/**
* @author wxb
* Java的四种引用
* 强引用:拥有强引用的对象无论何时都不会被垃圾回收
* 软引用:只拥有软引用的对象当内存不足时,会被垃圾回收
* 弱引用:只拥有弱引用的对象会在垃圾收集运行时被回收
* 虚引用:只拥有虚引用的对象和没有引用一样,只不过它被垃圾回收时会被放入关联的引用队列,并可被观察到
*
*/
public class FourReferenceTest {
/**
* @param args
*/
public static void main(String[] args) {
//三个测试,测试其中一个时请注释掉其他两个
PhatomReferenceTest();
// WeakReferenceTest();
// SoftReferenceTest();
}
static void PhatomReferenceTest(){
String s = new String("abc");
//创建一个引用队列rq,然后用rq和s一起创建一个虚引用
final ReferenceQueue<String> rq = new ReferenceQueue<String>();
PhantomReference<String> wr = new PhantomReference<String>(s,rq); //wr.get()会永远返回null
s = null;
//创建一个线程来循环检测s是否加入了队列
new Thread(){
boolean bFlag = true;
@Override
public void run() {
Object obj = null;
while(bFlag){
obj = rq.poll(); //rq中终会poll出一个PhantomReference
if(obj != null){
bFlag = false;
try {
//使用反射的原因是PhantomReference的get方法始终返回null
//即使向上转型为Reference也不行,因此只能通过反射直接得到存储在Reference类中的referent
Field f = Reference.class.getDeclaredField("referent");
f.setAccessible(true);
String s = (String) f.get(obj);
System.out.println("get String from PhantomReference :"+s);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}.start();
try {
//主线程休眠后运行gc,等待子线程运行
Thread.sleep(1000);
System.gc();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static void WeakReferenceTest(){
String s = new String("abc");
WeakReference<String> wr = new WeakReference<String>(s);
s = null;
while(wr.get() != null){
System.out.println("WeakReference get :"+wr.get());
System.gc();
System.out.println("System.gc()");
}
}
/**
* 不到内存耗尽该测试不会退出
*/
static void SoftReferenceTest(){
String s = new String("abc");
SoftReference<String> wr = new SoftReference<String>(s);
s = null;
while(wr.get() != null){
System.out.println("SoftReference get :"+wr.get());
System.gc();
System.out.println("System.gc()");
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/logicteamleader/article/details/46654397