6

以下是实现单例的两种方法。各自的优点和缺点是什么?

静态初始化:

class Singleton {
    private Singleton instance;
    static {
        instance = new Singleton();
    }
    public Singleton getInstance() {
        return instance;
    }
}

延迟初始化是:

class Singleton {
    private Singleton instance;
    public Singleton getInstance(){
        if (instance == null) instance = new Singleton();
        return instance;
    }
}
4

5 回答 5

9
  1. 同步存取器

    public class Singleton {
        private static Singleton instance;
    
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }
    
    • 懒加载
    • 低性能
  2. 双重检查锁定和易失性

    public class Singleton {
        private static volatile Singleton instance;
        public static Singleton getInstance() {
            Singleton localInstance = instance;
            if (localInstance == null) {
                synchronized (Singleton.class) {
                    localInstance = instance;
                    if (localInstance == null) {
                        instance = localInstance = new Singleton();
                    }
                }
            }
            return localInstance;
        }
    }
    
    • 懒加载
    • 高性能
    • JDK应该是1,5 ++
  3. On Demand Holder 成语

    public class Singleton {
    
        public static class SingletonHolder {
            public static final Singleton HOLDER_INSTANCE = new Singleton();
        }
    
        public static Singleton getInstance() {
            return SingletonHolder.HOLDER_INSTANCE;
        }
    }
    
    • 懒加载
    • 高性能
    • 不能用于非静态类字段
于 2014-03-19T06:12:24.607 回答
5

第一个是急切的初始化。急切的初始化甚至在它被使用之前就创建了实例,这不是使用的最佳实践。

第二个是延迟初始化。惰性实现在单线程环境下工作得很好,但是对于多线程系统,如果多个线程同时在 if 循环中,它可能会导致问题。它将破坏单例模式,两个线程将获得单例类的不同实例。

请访问:http ://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples#static-block-initialization了解更多信息

于 2014-03-19T06:17:47.647 回答
1

让你的课像这样

public class Singleton {

private Singleton() {

}

private static Singleton instance;

public static Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}

}

并称之为..

Singleton instance = Singleton.getInstance();
于 2014-03-19T06:02:49.237 回答
1

注意:静态块只能直接访问在静态块外部定义的静态变量。您希望限制为仅创建一个实例的对象应该是static。您的第一种方法在编译期间失败,第二种方法要求您首先创建对象
遵循此方法:

class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static Singleton getInstance()
{
    if(instance == null)
         instance = new Singleton();
    return instance;
}
}

确保不在其他地方创建对象,因此将构造函数更改为私有

于 2014-03-19T06:14:04.780 回答
0

静态初始化程序不能抛出异常并将 RuntimeExceptions 吸收到 ClassDefNotFoundException 中,这不会停止执行。所以你可以在你的日志中看到很多 ClassDefNotFoundException,你甚至可能直到很久以后才意识到有问题,因为执行仍在继续。

第二种方法允许 RuntimeExceptions 停止执行。

更多细节在这里: https ://twasink.net/2006/07/07/how-not-to-handle-exceptions-from-static-code-block-in-java/

于 2018-09-27T01:09:18.590 回答