单例设计模式(二) - 常见几种写法

前言

单例设计模式(一) - 定义、volatile关键字好处
单例设计模式(二) - 常见几种写法
单例设计模式(三) - 强大的Activity的管理

1. 概述


上篇文章讲解了单例设计模式的套路及volatile作用,那么这篇文章就记录下单例设计模式常见的几种写法。

最常见的有3种:

1>: 单例 - 懒汉式(同步锁:DCL)

只有在使用的时候,才会去new 对象;
DCL定义:就是单例设计模式的懒汉式的同步锁方式

/**
 * Email: [email protected]
 * Created by Novate 2018/5/6 11:15
 * Version 1.0
 * Params:
 * Description:    单例 - 懒汉式: (同步锁:DCL)
 *                 只有在使用的时候,才会去new 对象
 *                 DCL定义:就是单例设计模式懒汉式同步锁的方式
*/

public class SingleTon3 {

    // 只有在使用的时候,才会去 new 对象,比较高效
    // 但是会有问题? 多线程并发的问题,如果多线程调用还是会存在多个实例的

    // 加上 volatile 好处是什么?
    // 1.防止重新排序
    private static volatile SingleTon3 mInstance ;

    private SingleTon3(){

    }


    /**
     * 双重校验加同步锁 synchronized:
     *      既保证线程安全,同时也保证效率比较高
     *      但是可能还会有问题,
     */
    public static SingleTon3 getInstance(){
        if (mInstance == null){
            synchronized (SingleTon3.class){    // 这个if只能进来一次,第二次就不会进来了
                if (mInstance == null){
                    mInstance = new SingleTon3() ;
                }
            }
        }

        return mInstance ;
    }
}
2>:单例 - 静态内部类
  1. 保证线程的安全;
  2. 用到的时候才会去 new SingleTon()对象
/**
 * Email: [email protected]
 * Created by Novate 2018/5/6 12:10
 * Version 1.0
 * Params:
 * Description:    单例 - 静态内部类(比较常用)
 *                  1. 保证线程的安全;
 *                  2. 用到的时候才会 new SingleTon() 对象;
*/

public class SingleTon {

    private SingleTon(){
    }

    public static SingleTon getInstance(){
        return SingleTonHolder.mInstance ;
    }

    public static class SingleTonHolder{
        private static volatile SingleTon mInstance = new SingleTon() ;
    }
}
3>:单例 - 容器管理(系统服务就用的这种 getSystemService())
/**
 * Email: [email protected]
 * Created by Novate 2018/5/6 12:10
 * Version 1.0
 * Params:
 * Description:    单例 - 容器管理(系统服务里边用的这种 getSystemService())
*/

public class SingleTon {

    private static Map mSingleMap = new HashMap<>() ;

    private SingleTon(){
    }

    /**
     * 用静态的方式把 SingleTon对象初始化好了
     */
    static {
        mSingleMap.put("activity_manager" , new SingleTon()) ;
    }

    public static Object getService(String serviceName){
        return mSingleMap.get(serviceName) ;
    }
}

几种不常用的单例写法:

1>:单例 - 懒汉式: 随着类的启动就已经 new 了 mInstance对象了

一般不会这么用,不太好;

/**
 * Email: [email protected]
 * Created by Novate 2018/5/6 11:10
 * Version 1.0
 * Params:
 * Description:    单例 - 饿汉式:随着类的启动就已经 new 了一个对象了 (一般不会这么用,不太好)
*/

public class SingleTon {

    // 随着类的启动就已经 new 了一个对象了,但是可能我们只是想在用的时候再去 new 对象
    private static SingleTon mInstance = new SingleTon();

    private SingleTon(){
    }

    public static SingleTon getInstance(){
        return mInstance ;
    }
}
2>:单例 - 懒汉式:只有在使用的时候,才会去new 对象
/**
 * Email: [email protected]
 * Created by Novate 2018/5/6 11:15
 * Version 1.0
 * Params:
 * Description:    单例 - 懒汉式:只有在使用的时候,才会去new 对象
*/

public class SingleTon1 {

    // 只有在使用的时候,才会去 new 对象,比较高效
    // 但是会有问题? 多线程并发的问题,如果多线程调用还是会存在多个实例的
    private static SingleTon1 mInstance ;

    private SingleTon1(){
    }

    /**
     * 加同步锁 synchronized:
     *      虽然解决了线程安全的问题,但是率可能会比较低,
     *      因为每次获取mInstance对象都要经过同步锁的判断;
     */
    public static synchronized SingleTon1 getInstance(){
        if (mInstance == null){
            mInstance = new SingleTon1() ;
        }

        return mInstance ;
    }
}
3>:单例 - 懒汉式:只有在使用的时候,才会去new 对象
/**
 * Email: [email protected]
 * Created by Novate 2018/5/6 11:15
 * Version 1.0
 * Params:
 * Description:    单例 - 懒汉式:只有在使用的时候,才会去new 对象
*/

public class SingleTon2 {

    // 只有在使用的时候,才会去 new 对象,比较高效
    // 但是会有问题? 多线程并发的问题,如果多线程调用还是会存在多个实例的
    private static SingleTon2 mInstance ;

    private SingleTon2(){
    }

    /**
     * 双重校验加同步锁 synchronized:
     *      既保证线程安全,同时也保证效率比较高
     *      但是可能还会有问题,
     */
    public static SingleTon2 getInstance(){
        if (mInstance == null){
            synchronized (SingleTon2.class){    // 这个if只能进来一次,第二次就不会进来了
                if (mInstance == null){
                    mInstance = new SingleTon2() ;
                }
            }
        }

        return mInstance ;
    }
}
4>:单例 - 自成一派写法

其实只要满足整个程序中只有一个实例对象就可以,代码可以随便写

/**
 * Email: [email protected]
 * Created by Novate 2018/5/6 12:25
 * Version 1.0
 * Params:
 * Description:    单例 - 自成一派
*/

public class SingleTon {

    private static SingleTon mInstance ;

    static {
        mInstance = new SingleTon() ;
    }

    private SingleTon(){
    }

    public static SingleTon getInstance(){
        return mInstance ;
    }
}

代码已上传至github:
https://github.com/shuai999/Architect_day8.git

你可能感兴趣的:(单例设计模式(二) - 常见几种写法)