[英]Does Singleton class with its instance as volatile make the instance data to be load again?
在我的应用程序中,服务器类是在启动时加载的,所有数据都被缓存一次。
这是一个单例类,其实例变量不是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
}
是的-在没有volatile
,您拥有臭名昭著的“双重检查锁定”反模式,它不是线程安全的(即使看起来如此)。 (即使使用volatile,使用Java 5之前的Java版本也不是线程安全的)。
http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
但是,尽管它的线程安全且使用volatile
并且Java> = 5,但它的代码很丑,所以您应该编写一个简单的synchronized
getInstance
方法...
public static synchronized Server getInstance() {
if (server == null) server = new Servier(...);
return server;
}
...或使用按需持有人模式的初始化程序:
private static class ServerHolder {
public static Server server = new Server(...);
}
public static Server getInstance() {
return ServerHolder.server;
}
因为ServerHolder
类是在第一次使用时延迟加载的,所以在首次调用getInstance
时将发生类初始化,因此Server
将被延迟实例化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.