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

前言

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

1. 概述


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

最常见的有3种:

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

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

/**
 * Email: 2185134304@qq.com
 * 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: 2185134304@qq.com
 * 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: 2185134304@qq.com
 * Created by Novate 2018/5/6 12:10
 * Version 1.0
 * Params:
 * Description:    单例 - 容器管理(系统服务里边用的这种 getSystemService())
*/

public class SingleTon {

    private static Map<String , Object> 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: 2185134304@qq.com
 * 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: 2185134304@qq.com
 * 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: 2185134304@qq.com
 * 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: 2185134304@qq.com
 * 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 单例模式(SingletonPattern)一般被认为是最简单、最易理解的设计模式,也因为它的简洁易懂,是项目中最...
    成热了阅读 4,304评论 4 34
  • 前言 本文主要参考 那些年,我们一起写过的“单例模式”。 何为单例模式? 顾名思义,单例模式就是保证一个类仅有一个...
    tandeneck阅读 2,541评论 1 8
  • 摘要:设计模式之一:单例模式目录介绍1.单例模式介绍2.单例模式定义3.单例模式使用场景4.单例模式的实现方式 4...
    肆虐的悲傷阅读 477评论 0 2
  • 一.什么是单例模式 单例模式的定义:确保一个类只有一个实例,并提供一个访问他的全局访问点。单例模式是几个设计模式中...
    Geeks_Liu阅读 2,249评论 0 10
  • 写在前面:这是一篇自我梳理性质的文章,如果也可以给大家带来一些思考,那么荣幸至极。 我写什么?我能写什么?我想写...
    FromHeart101阅读 415评论 1 2