简介
单例模式是java23中设计模式之一,也是最常见的一种模式。
使用场景
- 整个程序运行中只允许有一个类的实例
- 需要频繁创建然后销毁的对象
- 创建对象时耗时过多或者耗资源过多,但又经常用到的对象
- 方便资源相互通信的环境
单例的几种模式
线程不安全的懒汉式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Singleton {
private static Singleton singleton;
private Singleton(){ }
/** * @author czj * 线程不安全懒汉式单例模式 * @date 2020/6/14 23:41 * @param [] * @return com.czj.design.Singleton */ public static Singleton getInstance(){ if (singleton==null){ singleton = new Singleton(); } return singleton; } }
|
在需要的时候才创建实例,节省内存空间,但是多线程同时访问会导致返回多个实例。
饿汉式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| /** * 创建在 2020/6/14 23:38 */ public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){ } /** * @author czj * 饿汉式单例模式 * @date 2020/6/14 23:54 * @param [] * @return com.czj.design.Singleton */ public static Singleton getInstance(){ return singleton; } }
|
通过JVM的类加载机制实现了初始化,保证了线程安全。
线程安全懒汉式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| /** * 创建在 2020/6/14 23:38 */ public class Singleton {
private static Singleton singleton
private Singleton(){ } /** * @author czj * 线程安全懒汉式 * @date 2020/6/14 23:55 * @param [] * @return com.czj.design.Singleton */ public static Singleton getInstance(){ if (singleton==null){ synchronized (Singleton.class){ if (singleton==null){ singleton = new Singleton(); } } } return singleton; } }
|
通过双重加锁判断实现了线程安全,但是效率就慢了。
静态内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| /** * 创建在 2020/6/14 23:38 */ public class Singleton {
private Singleton(){ }
private static class Holder{ public static Singleton singleton = new Singleton(); }
/** * @author czj * 静态内部类 * @date 2020/6/15 14:59 * @param [] * @return com.czj.design.Singleton */ public static Singleton getInstance(){ return Holder.singleton; } }
|
通过JVM类加载机制保证线程安全。
枚举方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| /** * 创建在 2020/6/15 15:07 */
public enum SingletonEnum { INSTANCE(new Object());
private Object object; /** * @author czj * 枚举单例模式 * @date 2020/6/15 15:08 * @param [object] * @return */ SingletonEnum(Object object) { this.object = object; } }
|
通过枚举方式创建的单例模式,能保证线程安全而且能防止序列化重新创建对象。