设计模式--单例模式
如果文章哪里写错了,希望各位大哥大姐好心指出,十分感激
正文
什么是单例模式?
单例模式就是指我只会生成一个实例对象,你在使用过程中,虽然获取了多次,但你每次获取到的都是同一个对象。
为什么要使用单例模式?
单例的出现主要能解决两个问题:
1:提供一个全部唯一访问点,例如有一些全局变量,这些变量不会经常变化。
2:控制一些创建过程复杂的共享资源对象创建,例如数据库连接,或者日志文件的写入。创建过程比较耗时复杂,又不宜创建过多对象。
对于这两种情况,我们就可以使用单例,去控制对象的无意义创建,减少内存消耗。
怎样使用单例模式?
1:构造方法全部私有化。
2:提供一个唯一的静态方法去获取唯一实例对象。
单例有4种(网上有很多说5种7种,其实最重要的也就这4种):
1:饿汉模式单例(由classLoader控制,加载类时就创建了实例对象)
2;双重判断的懒汉单例(获取实例对象时才创建,用了synchronized关键字控制多线程并发)
3:静态内部类的懒汉单例(由classLoader控制,在获取实例对象时才会加载内部类,从而实现了懒加载)
4:枚举模式的单例(将枚举当成普通类来使用,既可以防止多线程并发,也可以防止反序列化创建对象)
饿汉模式单例和静态内部类的懒汉单例由classLoader来控制单例,这可能会产生两个或多个实例,原因:
如果当前的类的类加载器是自定义类加载器classLoader1,第一次加载单例类的时,根据双亲委派机制,他会委托“父亲”classLoader来进行加载,如果都没有能加载的,那就classLoader1来加载。
但如果好死不死,另外一个地方在获取这个单例类的时候,他用的是自定义类加载器classLoader2,根据双亲委派机制让他父亲来加载,又刚好碰巧还是没能加载上,那就是classLoader2来加载。
这样子这个单例就有了两个实例。
我个人更喜欢用枚举模式的单例,代码少了,还不用管多线程并发,头发瞬间多了
饿汉模式单例
/** * 简单饿汉单例 * */ class Single1 { private static Single1 instance = new Single1(); /** * 如果初始化单例很复杂,可以在静态代码块中进行初始化工作 * */ static { instance = new Single1(); /** 复杂的初始化工作 */ } private Single1() {} public static Single1 getInstance() { return instance; } }
双重判断的懒汉单例
/** * 双重判断的懒汉单例 * */ class Single2 { private static Single2 instance; private Single2() {} /** * 因为进行了两次if(instance == null)判断,所以就叫双重判断,可以防止多线程冲突 * */ public static Single2 getInstance() { if(instance == null) { synchronized(Single2.class){ if(instance == null) { instance = new Single2(); } } } return instance; } }
静态内部类的懒汉单例
/** * 静态内部类的懒汉单例 * */ class Single3 { private static class InnerClass{ private static Single3 instance = new Single3(); } private Single3() {} public static Single3 getInstance() { return InnerClass.instance; } }
枚举模式的单例
/** * 枚举的单例 * */ enum Single4{ instance; /** 一般业务方法 */ public void operation() { } }

浙公网安备 33010602011771号