单例设计模式
解决问题:保证一个类在内存中的对象唯一性
适用环境:对于多个程序适用同一个配置信息对象时,就需要保证该对象的唯一性
单例模式特点(如何保证对象唯一性?)
1、不允许其他程序用new创建该类对象
2、在该类创建一个本类实例。
3、对外提供一个方法让其他程序可以获取该对象
步骤:
1、私有化该类构造函数
2、通过new在本类中创建一个本类对象(私有静态化)
3、定义一个公有静态方法,将创建的对象返回
饿汉式:
1、类一加载,对象就已经存在了。
2、线程安全
public class Single{ private static Single single = new Single(); private Single(){} public static Single getInstance(){ return single; } }
懒汉式:
1、类加载进来,没有对象,只有调用了getInstance方法时,才会创建对象。(延迟加载)
2、线程不安全(需要自己实现)
不安全的原因:
假设开始线程0进入,判断instance为空,在将要创建实例时,cpu切换,
线程1又进来了,同样instance为空 创建了实例,这是cpu切换回来到0线程,继续创建实例
可见,经过分析共创建了 两个实例,还谈什么单例。
public class Single{ private static Single single=null; private Single(){} private static Single getInstance(){ if(s==null) s = new Single(); return s; } }
但是以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全。
1、在getInstance方法上加同步
public static synchronized Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }
2、双重检查锁定
public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }
3、静态内部类
public class Singleton { private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return LazyHolder.INSTANCE; } }
第三种方法最好,既实现了线程安全,有避免了同步带来的性能影响。

浙公网安备 33010602011771号