java - 其实例为 volatile 的 Singleton 类是否使实例数据再次加载?

标签 java synchronization singleton volatile

在我的应用程序中,服务器类在启动时加载,所有数据都缓存一次。

它是一个单例类,它的实例变量不是volatile 即

private static Server server;

经过findbug分析,我不得不把它改成volatile,(如下图

public class Server {
    private static volatile Server server;

    public static Server getInstance(){
        if(server == null){
            synchronized (Server .class) {
                if(server == null){
                    try {
                        server = new Server(....);
                    } catch (IOException e) {
                        Logger.logError(MODULE, "IO Error while creating server home location: " + strServerHome);
                        Logger.logTrace(MODULE, e);
                    }
                }
            }
        }
        return server;
    }.......
}

但是在阅读了有关堆栈上的 volatile 的文章和 Q/A 之后,我认为 volatile 会使数据再次加载,因为 volatile 使信息从内存中读取而不是从缓存中读取。

那么我应该让我的变量变易变吗?

如果不稳定,那么我是否必须一次又一次地加载我的数据?

最佳答案

通常认为创建线程安全单例的最安全方法是将其设为枚举...

 public enum Server{
      INSTANCE;

      public Server getInstance(){
          return INSTANCE;
      }

      private Server(){...}

      // rest of methods here
 }

Singleton:The Enum Way

关于java - 其实例为 volatile 的 Singleton 类是否使实例数据再次加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19025801/

相关文章:

java - Gradle 依赖关系树中星号和箭头符号的含义

java - 是否有任何工具可以重构Java代码库的编码样式?

java - if 和 else 语句

iphone - Objective-C 单例只响应类方法

java - 如何从 do while 循环内部检索变量值

Android SyncAdapter 回调

c# - 同步访问公共(public)数据

postgresql - 如何在 PostgreSQL 触发器函数中获取表名?

java - 使用 "private static"字段而不是 "private final static"字段是否存在线程安全或可见性问题

Angular 2在构造函数外注入(inject)依赖