1、单例模式产生的需求:
对于频繁使用的对象,例如一些工具类,为了在不同的地方调用一些公共方法,可能会在不同的地方去实例化工具类对象
但是从内容上来看,这些工具类不存储数据,只是通过他提供的方法来处理数据
所以可以理解为需要的时候拿来用,而不是再创建一个相同的实例
2、如何构造单例模式
1)最直接的方式就是
在工具类内部提供一个静态变量,在加载了的时候就创建一个公共的对象、如下
public class DatabaseUtil {
public static DatabaseUtil databaseUtil = new DatabaseUtil();
在使用的时候直接通过DatabaseUtil.databaseUtil获取实例
但是有个缺点,每个类都会默认提供一个空的构造函数,也就是外部调用的时候还是可能会通过new关键字进行实例化,那么这个静态变量的作用就不明显了
2)在第一种的基础上对构造函数进行私有化
如下
private static DatabaseUtil databaseUtil = new DatabaseUtil();; private DatabaseUtil(){ System.out.println("create DatabaseUtil"); } public static DatabaseUtil getInstance(){ return databaseUtil; }
这样可以保证每次只能访问到工具类内部提供的静态对象实例了
为什么这块要提供一个返回实例的静态方法?
3)如果我们的系统有很多这样的工具类
那么在系统初始化的时候就需要每个都要执行实例化过程,可能会影响初始化进程
所以需要对实例化这一步骤进行控制,在需要的时候进行初始化,也就是延迟加载
那么这个静态方法就可以做控制
public static synchronized DatabaseUtil getInstance(){ if(databaseUtil == null){ databaseUtil = new DatabaseUtil(); } return databaseUtil; }
加synchronized是为了防止多线程情况下创建多次
那么这样是否就行了?
由于synchronized的关键字,在多线程下可能会出现线程等待的情况,还是差一丢丢
那如何是好?
4)公式如下
public class DatabaseUtil { private static DatabaseUtil databaseUtil = null; private DatabaseUtil(){ System.out.println("create DatabaseUtil"); } private static class SingletonHolder { private static DatabaseUtil databaseUtil = new DatabaseUtil(); } public static DatabaseUtil getInstance(){ return SingletonHolder.databaseUtil; } }
使用内部类来进行实例化,系统初始化不会加载SingletonHolder,在调用getInstance方法时才会加载,一次加载多次使用
也不需要同步机制
可以满足大部分场景
如有不足,请指正