单例模式定义
Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)
单例模式优点
减少内存开支,减少系统性能开销。
单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
设置全局的访问点,优化和共享资源访问。
单例模式缺点
单例模式没有接口,扩展困难。
违背单一职责原则。
饿汉式
是否懒加载:否
是否线程安全:是
// 饿汉式单例模式
public class HungryManSingletonMode {
private static final HungryManSingletonMode INSTANCE = new HungryManSingletonMode();
private HungryManSingletonMode() {
}
public static HungryManSingletonMode getInstance() {
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(HungryManSingletonMode.getInstance().hashCode());
}).start();
}
}
}
懒汉式
是否懒加载:是
是否线程安全:需加synchronized保证线程安全
// 懒汉式单例模式
public class SlackerTypeSingletonMode {
private static SlackerTypeSingletonMode INSTANCE;
private SlackerTypeSingletonMode() {
}
// 不加synchronized线程不安全
public static /*synchronized*/ SlackerTypeSingletonMode getInstance() {
if (INSTANCE == null) {
INSTANCE = new SlackerTypeSingletonMode();
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(SlackerTypeSingletonMode.getInstance().hashCode());
}).start();
}
}
}
双重检查式
是否懒加载:是
是否线程安全:需加volatile解决DCL问题
// 双重检查式单例模式
public class DoubleCheckTypeSingletonMode {
// 不加volatile会有DCL问题
private static /*volatile*/ DoubleCheckTypeSingletonMode INSTANCE;
private DoubleCheckTypeSingletonMode() {
}
public static DoubleCheckTypeSingletonMode getInstance() {
if (INSTANCE == null) {
synchronized (DoubleCheckTypeSingletonMode.class) {
if (INSTANCE == null) {
INSTANCE = new DoubleCheckTypeSingletonMode();
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(DoubleCheckTypeSingletonMode.getInstance().hashCode());
}).start();
}
}
}
登记式
是否懒加载:是
是否线程安全:是
// 登记式/内部静态类单例模式
public class RegistrationTypeSingletonMode {
private static class RegistrationTypeSingletonModeHolder {
private static final RegistrationTypeSingletonMode INSTANCE = new RegistrationTypeSingletonMode();
}
private RegistrationTypeSingletonMode() {
}
public static final RegistrationTypeSingletonMode getInstance() {
return RegistrationTypeSingletonModeHolder.INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(RegistrationTypeSingletonMode.getInstance().hashCode());
}).start();
}
}
}
枚举式
是否懒加载:是
是否线程安全:是
// 枚举式单例模式
// 防止反射攻击
// 解决反序列化产生多例问题
public enum EnumerationTypeSingletonMode {
INSTANCE;
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(EnumerationTypeSingletonMode.INSTANCE.hashCode());
}).start();
}
}
}