【问题标题】:2 regarding Singleton pattern / Eager initialization and Synchronization2 关于单例模式/渴望初始化和同步
【发布时间】:2012-08-12 11:41:25
【问题描述】:

(来自维基百科)

//延迟初始化:

public class Singleton {

    private static volatile Singleton instance = null;

    private Singleton() {   }

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

//渴望初始化:

public class Singleton {
   private static final Singleton instance = new Singleton();

   private Singleton() {}

   public static Singleton getInstance() {
      return instance;
   }
}

“如果程序使用类,但可能不是单例实例本身,那么您可能需要切换到延迟初始化。”

1 - 不确定我明白了。为什么程序不应该使用类?为什么我不能通过添加属性/方法来解决它?常量引用应该如何改变?

2 - 在惰性初始化中 - 同步 getInstance() 而不是代码块(摆脱双重检查)如何影响我的程序,假设发生多线程?

谢谢。

【问题讨论】:

    标签: java synchronization singleton lazy-loading eager-loading


    【解决方案1】:

    1 - 您的应用程序可能包含各种 jar,但您不一定会使用每个 jar 中的所有功能。此外,您的应用程序的用户可能不会使用您内置的所有功能。例如,如果您有一个 ReportABug 类,他们可能永远不会从菜单中激活该功能,因为您是一位非常棒的程序员;-)

    在运行时需要该类之前,不会实例化/调用静态字段/方法,因此您的 ReportABug 类可能有 1000 个静态字段,但手指交叉,它们永远不会消耗任何内存,因为永远不会加载该类。

    他们的观点是具有单例(或多个)的类可能具有其他不访问单例的静态方法。

    2 - 您可以将方法与 Singleton 类对象同步,但每次调用 getInstance 都会产生开销,仅检查 instance == null (这是一个机器周期)要便宜得多。在外部 ==null 检查之后,另一个线程可能会抢占您的线程并创建实例,因此这两个测试都是必需的。

    【讨论】:

      【解决方案2】:
      1. 您并不总是使用每个类,可能通过您的程序的某些路径使用实例,而有些则不使用。
      2. 同步方法而不是块意味着每次有人想要引用时都必须获取锁。这是非常浪费的。您应始终将 synchronized 块尽可能小,以尽量减少锁争用。

      【讨论】:

        【解决方案3】:

        1- java 中有很多类,你并不总是使用它们。如果我用急切的初始化定义了一个单例类,而你不需要这个类,我最终会浪费内存。

        【讨论】:

          【解决方案4】:
          1. 这种技术称为双重检查锁定,在 JDK 1.5+ 中应避免使用。它用于低于 1.5 的 Java 版本,因为获取内在锁(进入同步块)的成本很高。这不再是真的,应该避免双重检查锁定。

          参考实践中的并发性 16.7 双重检查锁定反模式。不要这样做。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-12-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-20
            • 2018-06-26
            • 2020-06-19
            相关资源
            最近更新 更多