首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AtomicReference的单例

使用AtomicReference的单例
EN

Stack Overflow用户
提问于 2011-05-09 22:18:43
回答 6查看 7.4K关注 0票数 7

使用AtomicReference实现延迟初始化单例是正确的吗?如果没有-可能的问题是什么?

代码语言:javascript
复制
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicReference;

public class Singleton implements Serializable {

    private static final Singleton _instance = new Singleton();

    private static AtomicReference<Singleton> instance = new AtomicReference<Singleton>();

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance.compareAndSet(null, _instance)) {
            synchronized (_instance) {
                _instance.init();
                instance.set(_instance);
            }
        }
        return instance.get();
    }

    private void init() {
        // do initialization
    }

    private Object readResolve() throws ObjectStreamException {
        return getInstance();
    }

}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-05-09 22:20:16

不,这很糟糕:

代码语言:javascript
复制
public static Singleton getInstance() {
    // new "singleton" for every method call
    Singleton s = new Singleton();
                   ^^^^^^^^^^^^^^
    if (instance.compareAndSet(null, s)) {
        synchronized (s) {
            s.init();
        }
    }
    return instance.get();
}

使用AtomicReference是一个很好的想法,但它不会起作用,因为Java没有惰性计算。

经典的1.5版单例方法有:

渴望单例:

代码语言:javascript
复制
public final class Singleton{
    private Singleton(){}
    private static final Singleton INSTANCE = new Singleton();
    public Singleton getInstance(){return INSTANCE;}
}

具有内部保留器类的惰性单例:

代码语言:javascript
复制
public final class Singleton{
    private Singleton(){}
    private static class Holder{
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance(){return Holder.INSTANCE;}
}

枚举单例:

代码语言:javascript
复制
public enum Singleton{
    INSTANCE;
}

你也许应该坚持使用其中的一个

票数 12
EN

Stack Overflow用户

发布于 2011-05-09 22:30:04

您有一个争用条件,在init被调用之前,您可能会返回Singleton的一个实例。如果你想要一个只有一次的init,你可以包装单例。然而,我们知道如何以一种简单、高效的方式实现单例,可变的单例是纯粹的邪恶。

票数 1
EN

Stack Overflow用户

发布于 2011-05-09 22:20:09

您可以防止序列化场景强制使其成为单例。

所有的构造函数都应该是私有的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5938163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档