是否有必要添加volatile关键字以确保Java中线程安全的单例类? [英] Is there any need to add volatile keyword to guarantee thread-safe singleton class in java?

查看:171
本文介绍了是否有必要添加volatile关键字以确保Java中线程安全的单例类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据此帖子,线程安全的单例类应如下所示.但是我想知道是否需要向static CrunchifySingleton instance变量添加volatile关键字.因为如果实例被创建并存储在CPU缓存中,那么此时它不会被写回到主存储器,因此,另一个线程将在getInstance()方法上调用.会引起不一致的问题吗?

According to this post, the thread-safe singleton class should look as below. But I'm wondering whether there's a need to add volatile keyword to static CrunchifySingleton instance variable. Since if the instance is created and stored in CPU cache, at which time it is not written back to main memory, meanwhile, another thread invoke on getInstance() method. Will it incur an inconsistency problem?

public class CrunchifySingleton {

    private static CrunchifySingleton instance = null;

    protected CrunchifySingleton() {
    }

    // Lazy Initialization
    public static CrunchifySingleton getInstance() {
        if (instance == null) {
            synchronized (CrunchifySingleton.class) {
                if (instance == null) {
                    instance = new CrunchifySingleton();
                }
            }
        }
        return instance;
    }
}

推荐答案

我在上面回应@duffymo的评论:懒惰的单例远没有它们最初出现时有用.

I echo @duffymo's comment above: lazy singletons are nowhere near as useful as they initially appear.

但是,如果您绝对必须使用懒惰实例化的单例,则惰性持有人惯用语是实现线程安全的更简单方法:

However, if you absolutely must use a lazily-instantiated singleton, the lazy holder idiom is much a easier way to achieve thread safety:

public final class CrunchifySingleton {
  private static class Holder {
    private static final CrunchifySingleton INSTANCE = new CrunchifySingleton();
  }

  private CrunchifySingleton() {}

  static CrunchifySingleton getInstance() { return Holder.INSTANCE; }
}

此外,请注意,要真正成为单例,该类需要同时禁止实例化和子类化-构造函数必须为private,而类则必须为final.

Also, note that to be truly singleton, the class needs to prohibit both instantiation and subclassing - the constructor needs to be private, and the class needs to be final, respectively.

这篇关于是否有必要添加volatile关键字以确保Java中线程安全的单例类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆