[英]Factory for Thread Safe Singleton in Java
这是我一直用于工厂的基本模式的示例,它返回一个线程安全的Singleton:
public class UserServiceFactory {
private volatile static UserService userService;
private UserServiceFactory() { }
public static UserService getInstance() {
if (userService == null) {
synchronized(UserServiceImpl.class) {
if (userService == null) {
userService = new UserServiceImpl();
}
}
}
return userService;
}
}
它使用volatile和double check惯用法来确保创建单个实例并在线程中可见。
是否有更简洁和/或更便宜的方式来实现1.6+中的相同目标。
使用Initialization On Demand Holder习语,它更简单,更易读:
public class UserServiceFactory {
private UserServiceFactory () {}
private static class UserServiceHolder {
private static final UserService INSTANCE = new UserService();
}
public static UserService getInstance() {
return UserServiceHolder.INSTANCE;
}
}
但是,我更喜欢Just Create One成语。
更新 :正如您的问题历史记录所证实的那样,您正在使用Java EE。 如果你的容器支持它,你也可以使它成为@Singleton
EJB并使用@EJB
来注入它(尽管@Stateless
是优选的,因为@Singleton
默认是读锁定的)。
@Singleton
public class UserService {}
例如在JSF托管bean中
@EJB
private UserService userService;
这样,您可以将实例化作业委派给容器。
您可以让类加载器执行其maigc并在启动时初始化静态变量 - 这保证可以工作,因为类加载器可以保证单线程行为。
如果你想懒惰地初始化实例并且大多数是无锁的,那么不,你必须这样做,并确保你使用Java> = 1.5
编辑:请参阅BalusC的解决方案,该解决方案更智能地使用类加载器。 请注意,这一切都有效,因为类加载器懒惰地初始化类 - 即它们仅在第一次访问时加载 - 并且因为内部类在这方面就像普通类一样处理(仅仅因为加载外部类并不意味着内部类)加载了类)
为什么不呢
public synchronized static UserService getInstance() {
if (userService == null) {
userService = new UserServiceImpl();
}
return userService;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.