以下是实现单例的两种方法。每种方法的优点和缺点是什么?
静态初始化:
class Singleton {
private Singleton instance;
static {
instance = new Singleton();
}
public Singleton getInstance() {
return instance;
}
}
延迟初始化是:
class Singleton {
private Singleton instance;
public Singleton getInstance(){
if (instance == null) instance = new Singleton();
return instance;
}
}
答案 0 :(得分:9)
同步访问者
public class Singleton {
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Double Checked Locking&易失性
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
Singleton localInstance = instance;
if (localInstance == null) {
synchronized (Singleton.class) {
localInstance = instance;
if (localInstance == null) {
instance = localInstance = new Singleton();
}
}
}
return localInstance;
}
}
On Demand Holder成语
public class Singleton {
public static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
答案 1 :(得分:5)
首先是急切的初始化。 急切初始化甚至在使用之前就会创建实例,这不是最佳实践。
第二个是延迟初始化。 惰性实现在单线程环境中运行良好,但是当涉及到多线程系统时,如果多个线程同时位于if循环内,则会导致问题。它将破坏单例模式,两个线程将获得单例类的不同实例。
答案 2 :(得分:1)
让你的班级成为这样的
public class Singleton {
private Singleton() {
}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
并称之为..
Singleton instance = Singleton.getInstance();
答案 3 :(得分:1)
注意:静态块只能直接访问静态块外部定义的静态变量。要限制为仅创建一个实例的对象应为静态。您的第一个方法在编译期间失败,第二个方法要求您首先创建对象
遵循此方法:
class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static Singleton getInstance()
{
if(instance == null)
instance = new Singleton();
return instance;
}
}
确保在其他地方没有创建对象,因此将构造函数更改为private
答案 4 :(得分:0)
静态初始化程序无法引发异常,也不能将RuntimeException吸收到ClassDefNotFoundException中,而不会中断执行。所以你可以看到很多 在您的日志中记录了ClassDefNotFoundException,您甚至可能直到很久以后才意识到出现了问题,因为执行继续。
第二个方法允许RuntimeExceptions停止执行。
更多详细信息在这里: https://twasink.net/2006/07/07/how-not-to-handle-exceptions-from-static-code-block-in-java/