当前位置: 首页 > 面试题库 >

Java Singleton和一个内部类-什么保证线程安全?

闾丘博超
2023-03-14
问题内容

一个共同的(1,2)实现单的方式是使用具有静态构件的内部类:

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

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

    private Singleton() {
        //...
    }
}

据说此实现是延迟初始化的,并且是线程安全的。但是到底什么能保证其线程安全呢?处理 线程和锁的 JLS
17
并未提及静态字段具有任何类型的
事前发生 关系。如何确定初始化仅发生一次并且所有线程都看到相同的实例?


问题答案:

我们首先需要了解两点:

加载类时,静态初始化 发生 一次

在声明中具有static修饰符的 字段 称为 静态字段
或类变量。它们与类关联,而不与任何对象关联。该类的每个实例共享一个类变量,该变量位于内存中的一个固定位置

....

类的初始化包括执行其静态初始化程序和该类中声明的静态字段(类变量)的初始化程序

这意味着静态初始化器在初始化对象类(实际的 Class 对象,而不是 的实例)时仅执行一次。

因为Java编程语言是多线程的,所以类或接口的初始化需要仔细的同步,因为某些其他线程可能试图同时初始化同一类或接口。

对于每个类或接口 C ,都有一个唯一的初始化锁 LC 。从 CLC 的映射由Java虚拟机实现决定。

现在,用简单的话来说,当两个线程尝试初始化instance第一个获取 LC的
线程时,它实际上是初始化的线程instnace,并且因为它是静态进行的,所以java承诺它只会发生一次。

有关初始化锁的更多信息,请阅读JSL
17。



 类似资料:
  • 问题内容: 如标题所述,为什么静态嵌套类单例线程安全? 问题答案: 您显示的代码在技术上不是线程安全的。这种狡猾的代码通常会造成混乱。 该代码应如下所示: 在这里,我们在()的静态初始化程序中进行分配,任何以正确 的事前发生 关系访问它的线程都可以看到它。嵌套类没有什么特别的,它只允许使用外部类而无需立即构造单例对象。几乎可以肯定,这是完全 没有意义的,但似乎可以使某些人满意。 和以往一样,[ 可

  • 本文向大家介绍如何保证线程安全?相关面试题,主要包含被问及如何保证线程安全?时的应答技巧和注意事项,需要的朋友参考一下 考察点:线程 通过合理的时间调度,避开共享资源的存取冲突。另外,在并行任务设计上可以通过适当的策略,保证任务与任务之间不存在共享资源,设计一个规则来保证一个客户的计算工作和数据访问只会被一个线程或一台工作机完成,而不是把一个客户的计算工作分配给多个线程去完成。

  • 问题内容: 是否有任何书面证明的线程安全保证?javadoc暗示了它,但没有直接解决它: 返回字符串对象的规范表示。最初为空的字符串池由String类私有维护。 调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。 因此,对于任意两个字符串s和t,当且

  • 我很难理解内部类线程的行为。 它总是打印出“main”,并且线程是按顺序执行的。为什么内部类线程的执行由主线程执行? 谢谢!

  • 本文向大家介绍静态内部类单例 线程安全-Java版相关面试题,主要包含被问及静态内部类单例 线程安全-Java版时的应答技巧和注意事项,需要的朋友参考一下 我比较倾向于使用静态内部类的方法,这种方法也是《Effective Java》上所推荐的。 这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,

  • 本文向大家介绍在 Java 程序中怎么保证多线程的运行安全?相关面试题,主要包含被问及在 Java 程序中怎么保证多线程的运行安全?时的应答技巧和注意事项,需要的朋友参考一下 方法一:使用安全类,比如 Java. util. concurrent 下的类。 方法二:使用自动锁 synchronized。 方法三:使用手动锁 Lock。 手动锁 Java 示例代码如下: