单例模式
定义:
确保一个类只有一个实例,并提供UI个全局访问点
介绍:
属于创建型
适用于需要确保任何情况下都绝对只有一个实例
优点:
在内存中只有一个实例,减少了内存开销
可以避免对资源的多重占用
设置全局访问点,严格控制访问
缺点:
没有接口,修改困难
重点:
1. 私有构造器
2. 线程安全
3. 延迟加载
4. 序列化和反序列化安全
代码实现
1. 饿汉式
public class Singleton1 {
private Singleton1() {
}
private static Singleton1 instance = new Singleton1();
public static Singleton1 getInstance() {
return instance;
}
}
缺点:
会创建多余的对象,造成内存浪费
2. 懒汉式
public class Singleton2 {
private Singleton2() {
}
private static Singleton2 instance;
public static Singleton2 getInstance() {
if (null == instance) {
instance = new Singleton2();
}
return instance;
}
}
缺点:
instance = new Singleton2(); 这一步可能还未初始化完成就有新的进程进入,导致多个线程创建多个对象,所以是线程不安全的
3. Double Check Lock(DCL)
public class Singleton3 {
private Singleton3() {
}
private static Singleton3 instance;
public static Singleton3 getInstance() {
if (null == instance) {
synchronized (Singleton3.class) {
if (null == instance) {
instance = new Singleton3();
}
}
}
return instance;
}
}
缺点:
instance = new Singleton3();
1. 分配内存给对象
2. 初始化对象
3. 设置改对象指向刚分配的地址
2,3步线程不强制要求顺序,所以可能会出现多个线程抢对象的情况导致出错
可以给对象添加volite关键字,来保证顺序
4. 枚举实现单例
public enum Singleton4 {
INSTANCE;
public void doSomeThing(){
System.out.println("do some thing");
}
}
5. 静态内部类实现单例
public class Singleton5 {
private Singleton5() {
}
public static Singleton5 getInstance() {
return SingletonHolder.instance;
}
private static class SingletonHolder{
private static final Singleton5 instance = new Singleton5();
}
}
Jvm会对Class对象的初始化操作加锁,强制下面的操作顺序执行
1. 分配内存给对象
2. 初始化对象
3. 设置改对象指向刚分配的地址