前言
单例模式,顾名思义,即只产生唯一实例的设计模式。一个类只有一个实例,即一个类只有一个对象实例。
优点
1. 减少系统开销及资源消耗。
2. 设置全局访问点,优化共享资源的使用。
注:对于以上优点,我们可以拿Java配置读取举例,对于固定的配置文件,我们完全可以设计一个单例类,读取配置文件,而避免每次都读取文件造成的系统开销,同时也优化了配置文件的使用。
应用场景
- Servlet
- 开源框架Spring中的默认bean配置模式
- 数据库连接池
- 项目中对于配置文件的处理
等等
写法分类
懒汉式单例模式(非线程安全)
1 2 3 4 5 6 7 8 9 10 11 12
| public class Demo_Singleton_01 { private static Demo_Singleton_01 instance=null; private Demo_Singleton_01(){ } public static Demo_Singleton_01 getInstance(){ if(instance==null){ instance=new Demo_Singleton_01(); } return instance; } }
|
说明:这种写法不常用,虽然实现了懒加载(lazy-loading),但未考虑线程安全问题,不适用于多线程情况。
懒汉式单例模式(线程安全)
1 2 3 4 5 6 7 8 9 10 11 12
| public class Demo_Singleton_02 { private static Demo_Singleton_02 instance=null; public static synchronized Demo_Singleton_02 getInstance(){ if(instance==null){ instance=new Demo_Singleton_02(); } return instance; } private Demo_Singleton_02(){ } }
|
说明:相对于demo1,这种写法实现了懒加载(lazy-loading),也考虑到线程安全问题,可适用于多线程情况。
饿汉式单例模式
1 2 3 4 5 6 7 8 9
| public class Demo_Singleton_03 { private static final Demo_Singleton_03 instance=new Demo_Singleton_03(); private Demo_Singleton_03(){ } public static Demo_Singleton_03 getInstance(){ return instance; } }
|
说明:饿汉式单例模式的明显缺点是无法实现懒加载,在类被创建后就创建了唯一实例。
饿汉式单例模式(变种)
1 2 3 4 5 6 7 8 9 10 11 12
| public class Demo_Singleton_04 { private static Demo_Singleton_04 instance=null; static{ instance=new Demo_Singleton_04(); } private Demo_Singleton_04(){ } public static Demo_Singleton_04 getInstance(){ return instance; } }
|
说明:可以看到这种方法和demo3的性质是一样的,只不过改为了静态块加载唯一实例。
静态内部类模式
1 2 3 4 5 6 7 8 9 10 11
| public class Demo_Singleton_05 { private static class Singleton{ private static final Demo_Singleton_05 instance=new Demo_Singleton_05(); } private Demo_Singleton_05(){ } public static final Demo_Singleton_05 getInstance(){ return Singleton.instance; } }
|
说明:这种方法既可以实现懒加载,也能保证线程安全。
双重锁单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Demo_Singleton_06 { private static volatile Demo_Singleton_06 instance=null; private Demo_Singleton_06(){ } public static Demo_Singleton_06 getInstance(){ if(instance==null){ synchronized(Demo_Singleton_06.class){ if(instance==null){ instance=new Demo_Singleton_06(); } } } return instance; } }
|
说明:可以看出,双重锁单例模式只有在第一次创建对象的时候才同步,因为创建对象后就没必要了,(实例唯一)相比懒汉式,效率明显提高,相比饿汉式,不用在类加载的时候就创建实例,而是等到什么时候想调用的时候在创建实例。线程安全,效率高。
枚举法
1 2 3 4 5 6
| public enum Demo_Singleton_07 { instance; public void doSomething(){ } }
|
说明:枚举法代码十分直观,线程安全,但是无法实现懒加载。
参考资料
- https://blog.csdn.net/goodlixueyong/article/details/51935526
- https://www.cnblogs.com/Ycheng/p/7169381.html
GitHub代码地址
https://github.com/JavaZWT/designPatterns