手写常用设计模式

单例模式

  单例模式核心在于为整个系统提供一个唯一的实例,为整个系统提供一个全局访问点。单例模式从实现上可以分为饿汉式单例和懒汉式单例两种,前者天生就是线程安全的,后者则需要考虑线程安全性。常见的线程安全的懒汉式单例的实现有内部类式和双重检查式两种。下面给出单例模式几种常见的形式:  

(1). 饿汉式单例

// 饿汉式单例
public class Singleton1 {

    // 指向自己实例的私有静态引用,主动创建
    private static Singleton1 singleton1 = new Singleton1();

    // 私有的构造方法
    private Singleton1(){}

    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton1 getSingleton1(){
        return singleton1;
    }
}

(2). 懒汉式单例

// 懒汉式单例
public class Singleton2 {

    // 指向自己实例的私有静态引用
    private static Singleton2 singleton2;

    // 私有的构造方法
    private Singleton2(){}

    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton2 getSingleton2(){
        // 被动创建,在真正需要使用时才去创建
        if (singleton2 == null) {
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
}

(3). 线程安全的懒汉式单例 —— 内部类方式

public class Singleton {
    //静态私有内部类
    private static class InnerClass {
        private final static Singleton instance = new Singleton();
    }

    private Singleton(){

    }

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

        内部类方式线程安全懒汉式单例的内在原理在于:虚拟机会保证一个类的类构造器()在多线程环境中被正确的加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的类构造器(),其他线程都需要阻塞等待,直到活动线程执行()方法完毕。特别需要注意的是,在这种情形下,其他线程虽然会被阻塞,但如果执行()方法的那条线程退出后,其他线程在唤醒之后不会再次进入/执行()方法,因为 在同一个类加载器下,一个类型只会被初始化一次。
(4). 线程安全的懒汉式单例 —— 双重检查方式

public class Singleton {

    // volatile: 防止指令重排序
    private volatile static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        // 第一次检查
        if(instance == null){
            // 只在最初几次会进入该同步块,提高效率
            synchronized(Singleton.class){
                // 第二次检查
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

 
单例模式整理于  作者:书呆子Rico    原文:https://blog.csdn.net/justloveyou_/article/details/78653660 

你可能感兴趣的:(开发之道)