以下是问题:
将单例设计模式实现为模板,以便对于任何给定的类 Foo,你可以调用Singleton :: instance()并获得指向单例实例的指针 Foo类型。假设存在一个具有acquire()和release()的类Lock 方法。你怎么能让你的实现线程安全且异常安全?
我的分析:
正如Joshua Bloch在“有效的java”中指出的那样,更好的实施方式 单例类是枚举和公共静态工厂方法。结合挥发性 和synchronized是我知道的方式使其线程安全和延迟初始化 如下public class myS{
private static volatile final _ins = null;
private myS(){};
public static myS getIns(){
synchronized(){
if(_ins==null) _ins = new myS();
}
return _ins;
}
}
此时,我对制作单身模板感到有点困惑。我的理解是我们要么具有泛型类型的接口,要么具有抽象类。只要客户实现它们,它们就是单例。所以,我的猜测解决方案如下:
public interface singleton<T>{
public T instance();
}
public class Foo implements singleton<T>{
private static volatile final Foo _ins = null;
public static Foo instance(){
synchronized(this)
if(_ins==null){
_ins = new Foo();
}
}
}
}
答案 0 :(得分:3)
获得单例功能的最简单方法是使用依赖注入(DI)框架,如Spring。使用DI也有很多其他好处。
答案 1 :(得分:0)
'singleton'不适合'template'。这是一种矛盾。如果认为您将更好地实施enums
,如下所示
public enum MySingleton1 {
;
public static void MethodA() { ... };
}
public enum MySingleton2 {
;
public static int MethodB() { ... };
}
修改强>
没有枚举的解决方案是:
public interface singletonMarker{};
public final class MySingleton1() extends singletonMarker {
public static final MySingleton1 INSTANCE = new MySingleton1();
private MySingleton1() {};
public synchronized int mySyncMethod() { ... };
}
用法
MySingleton1.INSTANCE.mySyncMethod();
界面仅作为标记,但实际上并不是必需的。