网上关于Java单例模式的讨论和探究已经远超出它本来产生的价值,这篇文章用来记录需要单例时的best practice.
饿汉单例
99%的情况下你都不需要懒汉单例(延迟初始化)
饿汉代码(JVM 类加载机制保证单例)
public class MySingleton {
private static final MySingleton instance = new MySingleton();
private MySingleton() {}
public static MySingleton getInstance() {
return instance;
}
}
还是需要延迟加载?
Initialization-on-demand holder idiom 单例 (JVM加载机制保证单例)
public class MyHolderSingleton {
private static final class Holder {
private static final MyHolderSingleton instance = new MyHolderSingleton();
}
private MyHolderSingleton(){}
public static MyHolderSingleton getInstance() {
return Holder.instance;
}
}
References
上面两种做法已经是基本可能需要场景的单例做法了,理解并记住他们,从此不再看单例了。
如果除了最佳实践,还需要探究单例的所有可能问题和原理,参看下表:
- https://stackoverflow.com/a/2521930/1468013 简单直接,要么饿汉方式,要么holder方式还有enum
- https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples 这是解释最全,覆盖最广的一篇,还包含了反射,序列化等等
- https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom holder的wikipedia
- http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization#anch102163 讲了双重检查锁定,要用volatile的原因
网友评论