不寻常的单例模式
单例模式
一.什么是单例模式?
单例模式是java中最简单的设计模式之一,属于创建型设计模式,这种模式涉及到一个的单一的类,该类负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。(1.单例类只能有一个实例,2.单例类必须自己创建自己唯一实例,2.单例类必须给其它对象提供这个实例)。
二.单例模式的应用场景有什么?
某些对象我们只需要一个实例的,比如:配置文件,工具类,线程池,缓存,日志对象等这些,如果创建的实例过多,就会导致一些问题,比如占用资源,结果不一致的现象等。
三.饿汉模式实例
/** * 单例模式Singleton * 应用场合:有些对象只需要一个就足够了,比如古代的皇帝 * 类型:饿汉模式 */ public class Singleton { //1.将构造方法私有化,不允许外部直接创建对象 private Singleton(){} //2.创建类的唯一实例,使用private static修饰 private static Singleton instance =new Singleton(); //3.提供一个用于获取实例的方法,使用public static修饰 public static Singleton getInstance(){ return instance; } }
四.懒汉模式实例
/** * 懒汉模式(线程不安全,安全的话加synchronized) */ public class Singleton { //1.将构造方法私有化,不允许外部直接创建对象 private Singleton(){} //2.声明类的唯一实例,使用private static修饰 private static Singleton instance =new Singleton(); //3.提供一个用于获取实例的方法,使用public static修饰 public static Singleton getInstance(){ if(instance==null){ return new Singleton() ; } return instance; } }
五.懒汉模式和饿汉模式有什么不同呢?
饿汉模式的特点是加载类的速度比较慢,但运行是获取对象的速度比较快,而且是线程安全的,懒汉模式的特点是加载类的速度比较快,但运行时获取对象的速度比较慢,而且不是线程安全的.
六.双重检查锁实例
/** * 这种方式采用双锁机制,安全且在多线程情况下能保持高性能。 */ public class Singleton { private volatile static Singleton instance =new Singleton(); private Singleton(){} public static Singleton getInstance(){ if(instance==null){ synchronized(Singleton.class){ if(instance==null){ return new Singleton(); } } } return instance; } }
七.登记证/静态内部类
/** * 这种方式能达到双检锁方式一样的功效,但实现更简单,当 Singleton类被装载了,instance 不一定被初始化。 * 因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时, * 才会显式装载 SingletonHolder类从而实例化 instance,比饿汉式合理。 */ public class Singleton { private static class SingletonHolder{ private static Singleton instance =new Singleton(); } private Singleton(){} public static Singleton getInstance(){ return SingletonHolder.instance; } }
八.枚举
/** *它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化 */ public enum Singleton { INSTANCE; private Object object=new Object(); private Singleton(){ object=new Object(); } public Object getObject(){ return object; } } class SingletonTest{ public static void main(String[] args){ Singleton.INSTANCE.getObject(); } }