在一个程序中,我需要将弱引用存储在某个存储引擎(实际上是嵌入式Prolog数据库)中。为了保持简单的解释,这种存储引擎可以被视为(在这个问题的上下文中)作为弱引用的集合。清理与弱引用相关的资源
我需要保证,一旦参考被回收,弱引用将从存储引擎中收回。换句话说,如果它的get()
方法已经返回null,就不应该从引擎访问弱引用。
我目前通过ReferenceQueue
执行此操作。
下面的代码延伸通过的添加cleanUp()
方法(该方法调用来自发动机删除弱引用的清洁任务)的装置弱引用:
public class MyWeakRef<REF_TYPE> extends WeakReference<REF_TYPE> {
MyWeakRef(REF_TYPE referent, ReferenceQueue<REF_TYPE> referenceQueue, Runnable cleaningTask, ...) {
super(referent, referenceQueue);
this.cleaningTask = cleaningTask;
...
}
void cleanUp() {
cleaningTask.run();
}
...
}
下面的代码显示的参考文献中是如何
public class WeakReferencesCleaner extends Thread {
private static WeakReferencesCleaner referencesCleaner = new WeakReferencesCleaner(new ReferenceQueue<Object>());
public static WeakReferencesCleaner getWeakReferencesCleaner() {
return referencesCleaner;
}
public synchronized static void startWeakReferencesCleaner() {
if(!referencesCleaner.isAlive())
referencesCleaner.start();
}
private ReferenceQueue<?> referenceQueue;
public WeakReferencesCleaner(ReferenceQueue<?> referenceQueue, int priority) {
this.referenceQueue = referenceQueue;
this.setDaemon(true);
}
public ReferenceQueue<?> getReferenceQueue() {
return referenceQueue;
}
@Override
public void run() {
while(true) {
try {
MyWeakRef<?> ref = (JTermRef<?>) referenceQueue.remove();
try {
ref.cleanUp();
} catch(Exception e) {
...
}
} catch (InterruptedException e) {}
}
}
}
虽然在我的测试中,这是工作的罚款,我发现了以下工作:在一个单独的线程从ReferenceQueue
需要回收的引用,并调用其cleanUp()
方法清洗所述WeakReference类的文档中:
假设垃圾回收器确定在 时间,一个对象是弱可某一点。那时它会原子上清除对该对象的所有弱引用......在相同的 时间或稍后的时间它将排入那些新引用的弱 引用,这些引用是用引用队列注册的。
因此,在引用无效的时间和方法cleanUp()
被执行时,另一个线程可以查询引擎并仍然找到无效的引用。
我的问题是:我怎么能保证在多线程的上下文中,失效的引用永远不会被我的引擎返回?
简短的回答,你不能。您需要更改您的要求或使用其他设施。 – jtahlborn
如果您想要提供替代解决方案的建议,则必须提供有关您尝试解决的问题的更多详细信息。 – jtahlborn
hi @jtahlborn通过使用“另一个设施”,你的意思是什么? – Sergio