首页 > 应用开发 > > 聊聊如何实现更优雅的单例?
来自:https://blog.csdn.net/weixin_43178828
public class MySingleton {
private static MySingleton instance = new MySingleton();
private Singleton() {
}
public static MySingleton getInstance() {
return instance;
}
}
MySingleton singleton = MySingleton.getInstance();public class MySingleton {
private static MySingleton instance = null;
private static OtherSingleton helper = null;
static{
helper = OtherSingleton.getInstance();
instance = MySingleton(helper);
}
private MySingleton(OtherSingleton helper) {
if(helper) this.helper = helper;
else throw new MyException("OtherSingleton getInstance failed");
}
public static MySingleton getInstance() {
return instance;
}
}
OtherSingleton 的getInstance负责 我们这里最多加一层检查 拦截抛异常 ) 不会出现 因为多线程 导致创建的时候 helper拿不到的情况。。getInstance里边也可以添加独特的东西(懒汉式我们后边再聊)getInstance时public class MySingleton {
private static MySingleton instance = null;
private static OtherSingleton helper = null;
private MySingleton(OtherSingleton helper) {
if(helper) this.helper = helper;
else throw new MyException("OtherSingleton getInstance failed");
}
public static MySingleton getInstance() {
if(instance == null)
instance = new MySingleton(OtherSingleton.getInstance());
return instance;
}
}
instance == null 当然进的来)synchronized 让整个代码块顺序执行 就类似static代码块一样:public class MySingleton {
private static MySingleton instance = null;
private static OtherSingleton helper = null;
private MySingleton(OtherSingleton helper) {
if(helper) this.helper = helper;
else throw new MyException("OtherSingleton getInstance failed");
}
public static synchronized MySingleton getInstance() {
if(instance == null)
instance = new MySingleton(OtherSingleton.getInstance());
return instance;
}
}
public class MySingleton {
private static MySingleton instance = null;
private static OtherSingleton helper = null;
private MySingleton(OtherSingleton helper) {
if(helper) this.helper = helper;
else throw new MyException("OtherSingleton getInstance failed");
}
public static synchronized MySingleton getInstance() {
if(instance == null){
synchronized (MySingleton.class){
if(instance == null){
instance = new MySingleton(OtherSingleton.getInstance());
}
}
}
return instance;
}
}
MySingleton.class对象 作为临界 意图明显 class对象唯一 所以我们锁类 这样就保证了单线程的创建实例 其实和static静态块异曲同工 因为static也是类初始化的时候执行的 同样也是保证串行 绑定了class对象的执行instance!多线程在下一个指令周期 抢到了CPU计算的时间片 执行 那个时候缓存默认是不更新的volatile 他自然是个native的关键字 底层依赖C来实现变量的可见性!所以我们终极的程序应当是:public class MySingleton {
private volatile static MySingleton instance = null;
private static OtherSingleton helper = null;
private MySingleton(OtherSingleton helper) {
if(helper) this.helper = helper;
else throw new MyException("OtherSingleton getInstance failed");
}
public static synchronized MySingleton getInstance() {
if(instance == null){
synchronized (MySingleton.class){
if(instance == null){
instance = new MySingleton(OtherSingleton.getInstance());
}
}
}
return instance;
}
}
static来创建了 但是可不可能用另外一个类的static来保证懒汉式单例呢?public class MySingleton {
private MySingleton(OtherSingleton helper) {
if(helper) this.helper = helper;
else throw new MyException("OtherSingleton getInstance failed");
}
public static class MySingletonAdapter {
private static final MySingleton instance = new MySingleton(OtherSingleton.getInstance());
}
public static getInstance() {
return MySingletonAdapter.instance;
}
}
Initialization on demand holderSerializable接口的单例 序列化倒没什么问题 但是反序列化时会产生新的实例对象 这里我们得改改readResolve()方法 使得返回的实例保证单例public class MySingleton {
private static final long serialVersionUID = -3453453414141241L;
private static MySingleton instance = new MySingleton(OtherSingleton.getInstance());
private MySingleton(OtherSingleton helper) {
if(helper) this.helper = helper;
else throw new MyException("OtherSingleton getInstance failed");
}
private Object readResolve() {
return instance;
}
}
OtherSingleton.getInstance() 但是有没有想过 系统刚开始一启动 实例化 谁先谁后呢?假设Other是后边才实例化的 前边的MySingleton的创建不是吃瘪了嘛???OtherSingleton初始化是需要MySingleton的 怎么办呢?如果几百个bean 初始化的时候互相依赖 该怎么解决?invertion of controll) 控制翻转思想 其实际实现是通过依赖注入dependency injection。来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69917606/viewspace-3156461/ ,如需转载,请注明出处,否则将追究法律责任。