01.概念
创建型模式,提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
02.重点
将构造方法设为私有,通过方法提供实例。
2.1 饿汉式
类加载到内存后,就实例化一个单例,JVM保证线程安全。
简单实用,推荐。
唯一缺点:不管用到与否,类加载时都会完成实例化。
public class Mgr01 {
private static final Mgr01 INSTANCE = new Mgr01();
private Mgr01() {
}
public static Mgr01 getInstance() {
return INSTANCE;
}
}
2.2 懒汉式
使用的时候才初始化,但相应的带来了线程不安全的问题
public class Mgr02 {
private static Mgr02 INSTANCE;
private Mgr02() {
}
public static Mgr02 getInstance() {
if (INSTANCE != null) {
INSTANCE = new Mgr02();
}
return INSTANCE;
}
}
为什么说线程不安全呢,当两个线程同时判断if (INSTANCE != null)且进入if内部,则会有两个Mgr02 new出来
那么线程不安全如何解决呢
我们尝试加锁
public class Mgr03 {
private static Mgr03 INSTANCE;
private Mgr03() {
}
public static synchronized Mgr03 getInstance() {
if (INSTANCE != null) {
INSTANCE = new Mgr03();
}
return INSTANCE;
}
}
这样每次在读取时都要进行加锁的操作,效率降低了
此时出现了双重检查单例写法,将锁加给属性
public class Mgr04 {
private static Mgr04 INSTANCE;
private Mgr04() {
}
public static Mgr04 getInstance() {
if (INSTANCE != null) {
synchronized (Mgr04.class){
if (INSTANCE != null) {
INSTANCE = new Mgr04();
}
}
}
return INSTANCE;
}
}
较为完美的方式, 静态内部类方式
public class Mgr05 {
private Mgr05() {
}
private static class Mgr05Holder {
private final static Mgr05 INSTANCE = new Mgr05();
}
public static Mgr05 getInstance() {
return Mgr05Holder.INSTANCE;
}
}
枚举
public enum Mgr06 {
INSTANCE;
}