Android面试题目之(九) 幽灵引用
Android面试题目之(9) 幽灵引用
幽灵引用是android中最不会使用的引用,其作为finalize的替代方案,可以避免finalize的timeout。但是有时候并不是很好用,应为其发生在finalize之后,而这时候,这个对象已经不复存在。
这里的思想是,对象不能不存在,这个时候用另外一个对象去表示对这个对象的引用。
这样的话,对象就可以存在了,类似智能指针。
当然我们也可以用weakreference 做类似的事情,weakreference最大的问题是,weakreference.get()返回null的时候, 不一定 finalize()已经被调用,这个顺序很难确定。当然我们其实也不关心这个,只要我们能够收到finalize()或者将要finalize()的事件就可以了。
package sort;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.List;
import sort.Refer.ReferInfo;
public class Refer<T extends Releasable> {
private static ReferenceQueue<Refer<? extends Releasable>> queue = new ReferenceQueue<>();
public static class ReferInfo<T extends Releasable> {
private T t;
private PhantomReference<Refer<? extends Releasable>> phantomRef = null;
}
private T t;
private static List<ReferInfo<Releasable>> mInfos = new ArrayList<>();
static {
start();
}
public static void start() {
new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (mInfos) {
queued = key.queue.remove(Integer.Max);
if (queued != null) {
for (ReferInfo<?> key : mInfos) {
//TODO:
if(key.phantomRef == queued){
System.out.println("enqueued!");
key.t.release();
}
mInfos.remove(key);
break;
}
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.gc();
}
}
}).start();
}
public Refer(T t) {
this.t = t;
ReferInfo<Releasable> info = new ReferInfo<>();
info.phantomRef = new PhantomReference<>(this, queue);
info.t = t;
synchronized (mInfos) {
mInfos.add(info);
}
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize");
}
}
下面是一个releasable
package sort; public interface Releasable { void release(); }
下面是一个使用方法:
package sort;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
public class PhantomreferenceStudy implements Releasable {
public static void main(String[] args) throws InterruptedException {
System.out.println(".....");
Refer refer = new Refer(new PhantomreferenceStudy());
refer = null;
while (true) {
System.gc();
}
}
@Override
public void release() {
//在这里做一些清理的工作。而不是finalize, 这个方法发生在finalize之前。
}
}
打印:
..... finalize enqueued!
完毕