文章内容
一、饿汉模式
01 02 03 04 05 06 07 08 09 10 11 | //饥饿模式 public final class EagerSingleton { private static EagerSingleton singObj = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getSingleInstance() { return singObj; } } |
性能问题:每个对象在没有使用之前就已经初始化了,如果这个对象很大呢?没有使用这个对象之前,就把它加载到了内存中去是一种巨大的浪费
二、懒汉模式
1、写法一
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | //懒汉模式 public final class LazySingleton { private static LazySingleton singObj = null ; private LazySingleton() { } public static LazySingleton getSingleInstance() { if ( null == singObj ) { singObj = new LazySingleton(); } return singObj; } } |
性能问题:线程不安全,多个线程可能同时运行判断singObj为null,于是同时进行了初始化
2、写法二
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | //懒汉模式加Synchronized public final class ThreadSafeSingleton { private static ThreadSafeSingleton singObj = null ; private ThreadSafeSingleton() { } public static Synchronized ThreadSafeSingleton getSingleInstance() { if ( null == singObj ) { singObj = new ThreadSafeSingleton(); } return singObj; } } |
性能问题:同步的代价必然会一定程度的使程序的并发度降低
3、写法三
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | //双重检查锁 public final class DoubleCheckedSingleton { private static DoubleCheckedSingletonsingObj = null ; private DoubleCheckedSingleton() { } public static DoubleCheckedSingleton getSingleInstance() { if ( null == singObj ) { Synchronized(DoubleCheckedSingleton. class ) { if ( null == singObj) { singObj = new DoubleCheckedSingleton(); } } } return singObj; } } |
优点:这种写法使得只有在加载新的对象进行同步,在加载完了之后,其他线程就可以判断跳过锁的的代价,做到很好的并发度
4、写法四
01 02 03 04 05 06 07 08 09 10 | //Initialization on Demand Holder public class Singleton { private static class SingletonHolder { public final static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } } |
优点: 这种方法使用内部类来做到延迟加载对象,在初始化这个内部类的时候,JLS(Java Language Sepcification)会保证这个类的线程安全。这种写法最大的美在于,完全使用了Java虚拟机的机制进行同步保证,没有一个同步的关键字
三、防止序列化破坏单例模式
1 2 3 4 | //添加这个hook函数,那么系统在反序列化的过程中就会通过该Hook方法得到原有的单例,而不是重新创建一个单例。 private Object readResolve() throws ObjectStreamException { return singleton; } |