最近,在接受以下代码的采访时,有人问我有关Java的问题,因为我是Java的新手,几乎没有Java代码,所以我真的不知道下面的代码做什么。
问题是使用以下代码选择描述最糟糕情况的选项:
public class Bolton { private static Bolton INST = null; public static Bolton getInstance() { if ( INST == null ) { INST = new Bolton(); } return INST; } private Bolton() { } }
这是此问题的选项
可以创建多个Bolton实例 博尔顿将永远不会被创造 构造函数是私有的,不能调用 可以对值进行垃圾收集,并且对getInstance的调用可能返回垃圾数据
以上哪个选项是正确的?又为什么呢?
这是一个单例模式
单例模式的想法是只有一个可用的类实例。因此,在这种情况下,constructor设置为private,并且该类维护一种getInstance()方法,该方法可以在此类中调用现有的实例变量INST,或者为执行的程序创建一个新的实例变量。答案可能是1,因为它不是线程安全的。对于我早些时候提到的3,可能会感到困惑,但这在技术上是设计使然,因此实际上不是缺陷。
constructor
private
getInstance()
INST
这是Wikipedia中的 Lazy Initialization (线程安全的单例模式)示例:
public class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { } public static SingletonDemo getInstance() { if (instance == null) { synchronized (SingletonDemo.class){ if (instance == null) { instance = new SingletonDemo(); } } } return instance; } }
设置实例变量可以volatile告诉Java从内存中读取它,而不是将其设置在缓存中。
volatile
同步的语句或方法有助于并发。
阅读有关双重检查锁定的更多信息,这对于“延迟初始化”单例会发生什么