书中介绍的单例模式是懒汉式的,除此之外还有几种实现方式,这里总结一下几种常用的单例模式和优缺点。
1.饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
优点:线程安全;没有加锁,效率高。
缺点:类装载时就实例化,比较浪费资源,可能会影响软件的启动速度。
2.懒汉式1,线程不安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:使用时才初始化,相比饿汉式比较节省“环保”。没有线程同步问题,运行效率高。
缺点:线程不安全。
适用于不要求线程安全的场景
3.饿汉式2,线程安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:线程安全。
缺点:使用锁机制,运行效率较低,而且锁的是getInstance方法,锁每次都得付出创建对象的代价。
适用于该方法使用不太频繁的场景。
4.双重锁
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
优点:解决了第三种锁代价太高的问题,只锁第一次运行的情况,但由于判空步骤在锁之前,所以并不能保证线程安全,所以在锁后面还需要一次判空,也就是双重锁。
缺点:实现比较复杂。