设计模式完结(3)单例模式

饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。

饿汉式:如果初始化比较麻烦,加载时间可能会比较长

懒汉式:单例类在第一次使用时创建,无须一直占用系统资源,实现了延迟加载,但是必须处理好多个线程同时访问的问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费大量时间,这意味着出现多线程同时首次引用此类的机率变得较大,双重检查锁定,这将导致系统性能受到一定影响

//懒汉式:
class
EagerSingleton { private static final EagerSingleton instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return instance; }
}
//饿汗式
class
LazySingleton { private volatile static LazySingleton instance = null; private LazySingleton() { } public static LazySingleton getInstance() { //第一重判断 if (instance == null) { //锁定代码块 synchronized (LazySingleton.class) { //第二重判断 if (instance == null) { instance = new LazySingleton(); //创建单例实例 } } } return instance; } }

解决两种方式的问题:饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。

延迟加载模式:*********** 定义一个内部类  定义final static 成员变量 

//Initialization on Demand Holder  
class Singleton {  
    private Singleton() {  
    }  

    private static class HolderClass {  
            private final static Singleton instance = new Singleton();  
    }  

    public static Singleton getInstance() {  
        return HolderClass.instance;  
    }  

    public static void main(String args[]) {  
        Singleton s1, s2;   
            s1 = Singleton.getInstance();  
        s2 = Singleton.getInstance();  
        System.out.println(s1==s2);  
    }  
}

第一次调用getInstance()时将加载内部类HolderClass,在该内部类中定义了一个static类型的变量instance,此时会首先初始化这个成员变量,由Java虚拟机来保证其线程安全性,确保该成员变量只能初始化一次。

通过使用IoDH,我们既可以实现延迟加载,又可以保证线程安全,不影响系统性能,不失为一种最好的Java语言单例模式实现方式(其缺点是与编程语言本身的特性相关,很多面向对象语言不支持IoDH)。

原文地址:https://www.cnblogs.com/wuer888/p/6679162.html