1.单例概念
作为一种常见的设计模式,单例模式的设计概念是"两个私有,一个公有",即私有属性/成员变量和私有构造,以及公有方法,常用于在整个程序中仅调用一次的代码。
2.具体操作
从单例模式的描述来看,单例模式并不能用于多次频繁调用的设计中,而更适用于程序开头,用于读取资源作启动作用的设计,在这里我们使用读取数据库的使用实例做例子。
单例模式的目标:在整个系统运行期间,只创建一个实例(对象)
单例模式的公有方法存在两个模式,分别为:懒汉式单例模式和饿汉式单例模式
3.示例
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/question?useUnicode=true&characterEncoding=utf8
jdbc.user=root
jdbc.password=123456
这是我们连接JDBC时的配置信息,我们最开始时通过把这些信息放在一个类中的常量里面来进行获取的,但事实上这些配置信息我们应该把它放在一个配置文件里的
4.懒汉式单例模式
class A{
//声明并私有化自己的对象(只声明不创建自己的对象)
private static A a = null;
//私有化构造方法
private A(){}
//对外创建一个自己的对象
public static A getA(){
//自己创建自己的对象,如果对象为空则重新创建
//不为空则直接返回自己创建的对象,以保证自己
//在程序运行中只创建一次对象
if(a == null){
synchronized(A.class){
if(a == null){
a = new A();
}
}
}
return a;
}
}
上述模式存在缺点,当该模式被多线程同时使用的时候,有可能会因此出现混乱,使两者交错,这时候我们可以通过使用再添加一重锁定(synchronized)的属性来保证线程安全。
5.饿汉式单例模式
饿汉式:(没有线程安全问题,但是没有延迟加载的效果,所以
一般不用)
class A{
//第二步就是自己声明并且自己创建自己的对象
private static final A a = new A();
//第一步就是私有化创造方法
private A(){}
//第三步就是提供静态的共有方法,返回出来这个对象
public static A getA(){return a;}
}
饿汉模式在创建的同时就提供了一个静态对象供程序调用,不会再发生变化,足矣保证现成安全
6.单例模式小结
单例模式 | 懒汉模式 | 饿汉模式 |
概念 | 在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例 | 在类加载的时候,就完成初始化 |
特点 | 类加载速度快,但是运行时获取对象的速度较慢。——“时间换空间” | 类加载较慢,但获取对象速度快。——“空间换时间” |
延迟加载 | 具备 | 不具备 |
线程安全 | 线程不安全 | 线程安全 |
7.两种单例模式的区别
饿汉模式:类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在
懒汉模式:只有当调用getInstance的时候,才会去初始化这个单例。
8.实现单例模式的步骤
1)私有化构造方法
2)自己创建自己的对象
3)对外提供一个共有的方法来返回自己创建的对象