多线程是Java threadsafe(和GCsafe)中的弱单例实现吗?
我希望取得以下成果:
- 我希望这个类的实例不超过一个。当类有多个引用时,我希望它们都引用同一个实例李>
- 除非有必要,否则我不想让实例出现。具体来说,我希望垃圾收集器能够在不使用时回收实例,并在下次请求实例时重新创建它李>
- 多个线程可能会请求一个实例,因此操作必须是线程安全的李>
这是我想出的代码:
public final class MyClass {
private static WeakReference<MyClass> instance;
public static synchronized MyClass getInstance() {
if ((instance == null) || (instance.get() == null)) {
instance = new WeakReference<MyClass>(new MyClass());
}
// TODO what if GC strikes here?
return instance.get();
}
}
设计选择包括:
- 延迟初始化,因此除非需要,否则不会创建实例
- 该类保留对实例的WeakReference,以便在不再使用该实例时可以对其进行垃圾收集李>
getInstance()
方法是synchronized
(toMyClass
),因此一次只能由一个线程执行李>
问题:
- 这个设计会像我预期的那样运行并产生预期的结果吗李>
- 我是否需要担心
getInstance()
被注释所在的垃圾收集器打断(这意味着垃圾收集器将回收我正要返回的实例)?如果是的话,我该如何应对李>
# 1 楼答案
在变量中保存
MyClass
的本地副本,而不是只将引用的唯一副本提供给WeakRefrence
的构造函数。这将防止GC在new WeakReference<MyClass>
调用和函数返回之间收集instance