阅读本文大概需要4分钟

什么是单例设计模式
所谓单例设计模式,其实就是确保类的实例对象只存在一个,并且将这个实例对象向外界提供出去。
单例设计模式的三种写法
(1) 饿汉式
package com.demo;
public class DanLi_01 {
private DanLi_01() {}
private static final DanLi_01 d = new DanLi_01();
public static DanLi_01 getDanLi_01() {
return d;
}
}只所以称之为饿汉式,简单可以理解为它比较饥渴,做什么事情都是很主动的,就是说它在类加载的时候,就已经将对象实例化,然后通过一个方法暴露给外部,从而获取该对象的实例。
(2) 懒汉式
package com.demo;
public class DanLi_02 {
private DanLi_02() {}
private static DanLi_02 danLi_02 = null;
public static synchronized DanLi_02 getDanLi_02() {
if (danLi_02 == null) {
return danLi_02 = new DanLi_02();
}
return danLi_02;
}
}我们再来看看懒汉式,我们很容易就可以发现,它跟饿汉式相比,它没有饿汉式那么饥渴,当类加载的时候,不会去创建对象,只有当我们调用获取实例的方法的时候,它会去做判断,如果不为null,表示对象已经创建,直接返回,如果为null,表示对象实例还没有创建,然后进行创建,将结果返回。
大家可能已经看出来了,就第一种方式和第二种方式之间如果做一个选择,大家可能都会选择第二种写法,我们再来看看第二种写法,细心的朋友可能看到我在方法上加了一个关键字synchronized,那么为什么要加这个关键字呢?
其实我们上面懒汉式的这种写法,没有是有考虑线程安全的问题的,如果不加这个关键字,那么它就有可能出现线程安全的问题,那么为了解决线程安全的问题,我们就使用synchronized关键字来解决。
这种写法看起来确实可以解决线程安全的问题,但是在效率方面它却不如接下来的第三种写法。
(3) 双重检查锁定
package com.demo;
public class DanLi_03 {
private DanLi_03() {}
private static DanLi_03 danLi_03 = null;
public static DanLi_03 getDanLi_03 () {
if (danLi_03 == null) {
synchronized (DanLi_03.class) {
if (danLi_03 == null) {
danLi_03 = new DanLi_03();
}
}
}
return danLi_03;
}
}那么为什么要这么写呢?我们可以看上面那个方法,每次获得对象实例的时候都要进行加锁,那么释放锁的这个过程是非常消耗性能的;再来看第三种写法就可以很轻松的看出来,在获得对象实例的过程中,只有对象为null的时候,才会进行加锁同步,如果对象已经存在,就不用每次进行加锁同步,那么这样就可以大大提升我们的效率,所以我们一般推荐第三种写法。
单例设计模式的特点
1、从代码中不难看出,必须私有构造器,因为外部不能直接new我们的对象,只能通过方法获得;
2、实例对象在应用中只存在一个;
3、单利设计模式必须把这个实例提供给其他对象;