Q
带参数的单实例化
4
A
回答
6
修改使用Bill Pugh's initialization on demand holder idiom的单例模式。这是线程安全的,没有专用语言结构(即易失性或同步)的开销:
public final class RInterfaceHL {
/**
* Private constructor prevents instantiation from other classes.
*/
private RInterfaceHL() { }
/**
* R REPL (read-evaluate-parse loop) handler.
*/
private static RMainLoopCallbacks rloopHandler = null;
/**
* SingletonHolder is loaded, and the static initializer executed,
* on the first execution of Singleton.getInstance() or the first
* access to SingletonHolder.INSTANCE, not before.
*/
private static final class SingletonHolder {
/**
* Singleton instance, with static initializer.
*/
private static final RInterfaceHL INSTANCE = initRInterfaceHL();
/**
* Initialize RInterfaceHL singleton instance using rLoopHandler from
* outer class.
*
* @return RInterfaceHL instance
*/
private static RInterfaceHL initRInterfaceHL() {
try {
return new RInterfaceHL(rloopHandler);
} catch (REngineException e) {
// a static initializer cannot throw exceptions
// but it can throw an ExceptionInInitializerError
throw new ExceptionInInitializerError(e);
}
}
/**
* Prevent instantiation.
*/
private SingletonHolder() {
}
/**
* Get singleton RInterfaceHL.
*
* @return RInterfaceHL singleton.
*/
public static RInterfaceHL getInstance() {
return SingletonHolder.INSTANCE;
}
}
/**
* Return the singleton instance of RInterfaceHL. Only the first call to
* this will establish the rloopHandler.
*
* @param rloopHandler
* R REPL handler supplied by client.
* @return RInterfaceHL singleton instance
* @throws REngineException
* if REngine cannot be created
*/
public static RInterfaceHL getInstance(RMainLoopCallbacks rloopHandler)
throws REngineException {
RInterfaceHL.rloopHandler = rloopHandler;
RInterfaceHL instance = null;
try {
instance = SingletonHolder.getInstance();
} catch (ExceptionInInitializerError e) {
// rethrow exception that occurred in the initializer
// so our caller can deal with it
Throwable exceptionInInit = e.getCause();
throw new REngineException(null, exceptionInInit.getMessage());
}
return instance;
}
/**
* org.rosuda.REngine.REngine high level R interface.
*/
private REngine rosudaEngine = null;
/**
* Construct new RInterfaceHL. Only ever gets called once by
* {@link SingletonHolder.initRInterfaceHL}.
*
* @param rloopHandler
* R REPL handler supplied by client.
* @throws REngineException
* if R cannot be loaded.
*/
private RInterfaceHL(RMainLoopCallbacks rloopHandler)
throws REngineException {
// tell Rengine code not to die if it can't
// load the JRI native DLLs. This allows
// us to catch the UnsatisfiedLinkError
// ourselves
System.setProperty("jri.ignore.ule", "yes");
rosudaEngine = new JRIEngine(new String[] { "--no-save" }, rloopHandler);
}
}
4
public class RInterfaceHL {
private static RInterfaceHL theInstance;
private final JRIEngine engine;
private RInterfaceHL(JRIEngine engine) {
this.engine = engine;
}
public static synchronized RInterfaceHL getInstance() {
if (theInstance == null) {
throw new IllegalStateException("not initialized");
}
return theInstance;
}
public static synchronized void initialize(String loopback) {
if (theInstance != null) {
throw new IllegalStateException("already initialized");
}
theInstance = new RInterfaceHL(new JRIEngine(loopback));
}
...
}
编辑:我要补充一点,如果你正在建设的东西在servlet或类似容器中运行,使用纯Singleton模式可能是一个坏主意。 IoC /依赖注入机制之一是一个更好的主意;例如春天在另一个答案建议。这使您可以将您的“单身人士”范围限定在容器中。
0
如果你只是在做一个小应用程序,但是依赖注入框架如Spring Framework可以给你单例行为,而不需要手动构造和初始化静态对象,这可能是矫枉过正的。
依赖注入“容器”将构造并将单例及其依赖类连接在一起,并可配置为使对象成为容器内的单例实例。
如果您之前没有使用过Spring,那么有一点学习曲线,但它是一个非常流行的框架,并且可能会很好地为您服务。
相关问题
- 1. 实例化参数化类
- 2. 带基本类型实例化模板参数的C++函数
- 3. 在运行时实例化带参数的加载的swf
- 4. 在运行时的Java实例化类,带参数
- 5. 不带参数的Autofac工厂实例化
- 6. 带有标识参数的C++模板实例化
- 7. 带参数的WCF服务实例
- 8. 带参数的单例的惰性初始化
- 9. 参数化单例模式
- 10. clojure实例?单参数
- 11. 带泛型的单例子参数
- 12. 实例化有很多参数的类
- 13. 没有充分实例化的参数
- 14. 类实例化的NULL参数
- 15. 实例化通用的参数
- 16. 实例方法与带参数参数的静态方法
- 17. 实例化单例类
- 18. 参数化类的java单例
- 19. Prolog - 参数没有充分实例化
- 20. 意图对象实例化参数
- 21. 参数没有被充分实例化
- 22. 实例化工厂参数角度
- 23. MVVM类实例化和参数
- 24. Scala - 使用参数实例化泛型?
- 25. Scala 2.12,实例化类型参数?
- 26. 使用参数实例化Python unittest.TestCase
- 27. Unity - 实例化时传递参数
- 28. 基于请求参数实例化类
- 29. 如何实例泛型参数化类
- 30. 来自数组的斯卡拉案例类参数实例化
请注意,单例不是每个JVM,而是每个类加载器。 Java中的单例模式是通过使类具有双重责任 - 实例创建和实际责任而获得的。当类加载类加载器时会处理实例创建责任(并且每个JVM可能有多个类加载器)。 – 2009-09-11 05:03:24