首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单例模式

单例模式
EN

Stack Overflow用户
提问于 2010-12-05 13:35:43
回答 4查看 519关注 0票数 1

下面的代码片段是直接的,

代码语言:javascript
复制
public MyClass getInstance() {
    if(uniqueInstance == null) {
        uniqueInstance = new MyClass();
    }
    return uniqueInstance;
}

下面的代码是做什么的?

代码语言:javascript
复制
public MyClass getInstance() {
    if(uniqueInstance == null) {
        synchronized(MyClass.class) {
            uniqueInstance = new MyClass();
        }
    }
    return uniqueInstance;
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-05 13:39:58

为了防止至少两个线程同时进入if块而导致的争用情况,使其成为线程安全是一个糟糕的尝试。

一种更安全的方法是添加额外的空检查,也称为double-checked locking

代码语言:javascript
复制
public MyClass getInstance() {
    if (uniqueInstance == null) {
        synchronized(MyClass.class) {
            if (uniqueInstance == null) {
                uniqueInstance = new MyClass();
            }
        }
    }
    return uniqueInstance;
}

然而,我通常更喜欢 pattern而不是单例。

票数 5
EN

Stack Overflow用户

发布于 2010-12-05 13:38:18

这是对线程安全的一点保障。

来自javaworld的文章here

同步该方法可确保对该方法的调用不会中断。

主要思想是,如果您没有synchronized块,则两个线程可以调用getInstance并重新初始化对象,从而可能丢失任何状态数据(如果您甚至应该在单例中具有状态数据)。

票数 3
EN

Stack Overflow用户

发布于 2010-12-05 19:12:44

我想你应该先从最简单的选项开始。最简单的单例是一个只有一个条目的枚举。考虑到类是延迟加载的,这仍然会导致延迟加载,除非直接引用类,而这不是很容易发生的。

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

为了避免意外加载,您可以使用内部类。

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

注意:这两种解决方案都不需要同步,因为它们使用类加载是线程安全的这一事实。

简而言之,有些情况下需要锁定,但不要让它变得比需要的更复杂。

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

https://stackoverflow.com/questions/4357538

复制
相关文章

相似问题

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