单例设计模式(Singleton)也叫单态设计模式
什么是单例设计模式?
单例设计模式 要求一个类有且仅有一个实例,并且提供了一个全局的访问点。这个单例不应该由人来控制,而应该由代码来限制。
单例设计模式的思路:
1.私有化构造函数
2.私有化静态类变量
3.对外提供获取实例的方法
常见的单例设计模式有两种:懒汉式,饿汉式
1,饿汉式--静态常量--类变量直接实例化
public class Singleton1 { //1.私有化构造函数 private Singleton1() { } //2.私有化静态类变量并直接实例化---类加载的时候就完成了实例化,final对于不同的应用场景可加可不加。 private final static Singleton1 INSTANCE = new Singleton1(); //3.对外提供获取该实例的方法 public static Singleton1 getInstance() { return INSTANCE; } }
小结:
优点:写法简单,类加载的时候就完成了实例化,避免了线程同步不安全的问题。
缺点:正由于类加载就完成实例化的特点,如果一直未使用该实例,那么就会造成内存的浪费。
2.饿汉式--静态代码块---类变量在静态代码块中被实例化
public class Singleton1 { //1.私有化构造函数 private Singleton1() { } //2.私有化静态类变量,并在静态代码块中为该变量赋值 private static Singleton1 INSTANCE; static { INSTANCE = new Singleton1(); } //3.对外提供获取该实例的方法 public static Singleton1 getInstance() { return INSTANCE; } }
小结:(其实这种写法与上面的写法类似,只是将直接赋值操作转移到了静态代码块中间接赋值,其实现原理相同,都是在类加载的时候完成了实例化)
优点:写法简单,类加载的时候就完成了实例化,避免了线程同步不安全的问题。
缺点:正由于类加载就完成实例化的特点,如果一直未使用该实例,那么就会造成内存的浪费。
3.懒汉式--双重(判断)加锁机制
public class Singleton { //1.私有化构造函数 private Singleton() { } //2.声明私有静态变量 private static Singleton instance; //3.给外界提供获取对象的方法 public static Singleton getInstance() { if (null == instance) { synchronized (Singleton.class) { if (null == instance) { instance = new Singleton(); } } } return instance; } }
小结:
这种写法是懒汉式单例设计模式较优的写法,实现了线程安全、延迟加载、性能较优。
4.懒汉式--静态内部类
public class Singleton { //1.私有化构造函数 private Singleton() { } //2.静态内部类:静态内部类在外部类Singleton加载的时候不会被实例化, // 而是在调用getInstance方法时,才会被加载完成实例化,这个特点为我们实现了延迟加载。 // 同时静态内部类只会在第一次加载的时候完成初始化,而在初始化过程中其他线程无法进入(JVM的功劳),从而保证了线程安全。 private static class SingletonInstance{ private static final Singleton INSTANCE = new Singleton(); } //3.对外提供获取实例的方法 public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }
小结:
这种设计模式完美的解决了饿汉式没有延迟加载的弊端,良好的解决了内存浪费问题。具有线程安全、延迟加载、效率高特点。
单例设计模式的应用场景:
1.工具类对象
2.创建对象时耗时过多或者消耗资源过多,但又经常使用的对象。比如:JDBC连接对象Connection,Redis连接对象Jedis等
3.频繁创建和销毁的对象