单例模式
单例模式确保系统中某个类只有一个实例,该类自行实例化并向整个系统提供这个实例的公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
单例模式优点:
1、系统中只存在一个共用的实例对象,无需频繁创建和销毁对象,节约了系统资源,提高系统的性能。
2、可以严格控制客户怎么样以及何时访问单例对象。
单例模式特点:
1、单例类只有一个实例。
2、单例类必须自己创建唯一实例。
3、单例类必须给所有其他对象提供这一实例。
使用场景:
重量级对象,不需要多个实例,如线程池,数据库连接池。
懒汉模式:延迟加载,只有在使用的时候实例化。
1、线程安全问题
2、double check 加锁优化
3、编译器(JIT),CPU有可能对指令进行重排序,导致使用到尚未初始化的实例,可以通过volatile关键字进行修饰,对于volatile修饰的变量可防止指令重排序。
饿汉式模式:类加载的初始化阶段完成了实例的初始化。本质上是通过JVM类加载机制,保证实例的唯一性。
类加载过程:
1,加载二进制数据到内存中,生成对应的Class数据结构。
2,连接:a.验证、b.准备(静态变量属性赋值)、c.解析。
3,初始化:静态变量属性赋值。
懒汉式(线程不安全)
public class LazySingleton {
private static LazySingleton lazySingleton;
private LazySingleton() {}
public static LazySingleton getInstance() {
if(lazySingleton==null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
懒汉式(线程安全)
public class LazySingleton {
private static LazySingleton lazySingleton;
private LazySingleton() {}
public synchronized static LazySingleton getInstance() {
if(lazySingleton==null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
懒汉式(双重检查锁 double-checked locking)
public class LazySingleton {
private volatile static LazySingleton lazySingleton;
private LazySingleton() {}
public static LazySingleton getInstance() {
if(lazySingleton==null){
synchronized (LazySingleton.class){
if(lazySingleton==null){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
}
饿汉式
public class HungrySingleton {
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton() {}
public static HungrySingleton getInstance() {
return hungrySingleton;
}
}
静态内部类
public class Singleton {
private static class SingletonInstance {
private static Singleton instance = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return SingletonInstance.instance;
}
}
枚举
public enum EnumSingleton {
INSTANCE;
}