程序员Java设计模式

JAVA设计模式-单例模式

2018-12-06  本文已影响7人  AdminFun

本文讲解GOF-23种设计模式其中的单例模式
单例模式说难吧,其实只有那么几句代码。
说简单吧,其实也要深入理解才能了解它的原理,废话少说,看代码

一、饿汉式写法

/**
 * 作者: Created by AdminFun
 * 邮箱: 614484070@qq.com
 * 描述: 饿汉式单例
 * 这种写法是最简单、也算是比较完美的写法,但是这种写法有一些缺点:
 * 1、instance的初始化是在类加载的时候完成的,所以不管你用不用都会初始化,可能造成资源浪费。
 * 2、如果初始化instance需要依赖其他的数据,那么这里就不能保证在初始化之前准备好。
 * 相比于饿汉式写法,有一种更加优美的写法,那就是懒汉式写法 {@link CarHelper1}
 */
public class CarHelper {

    private static final CarHelper instance = new CarHelper();

    private CarHelper() {
    }

    public static CarHelper getInstance() {
        return instance;
    }
}

二、懒汉式写法

/**
 * 作者: Created by AdminFun
 * 邮箱: 614484070@qq.com
 * 描述: 懒汉式单例
 */
public class CarHelper1 {

    /**
     * volatile 关键字的作用是禁止指令重排,用volatile修饰之后,
     * 对instance的读写操作就有一个内存保障,保证在完成写之前不会被调用读。
     * <p>
     * 想要了解上面一句话,则需要了解JVM中实例化执行过程:
     * 1、分配内存
     * 2、初始化成员变量,形成实例
     * 3、将对象指针指向该内存
     * 在多线程操作的时候,以上3个步骤可能会被交叉执行,造成错误内存,volatile就是用来解决这个问题的。
     * 不过在平常的一般开发中我们并没有这么严格的要求单例写法,因为在APP开发中很少遇到多线程操作或者我们根本不在乎这个问题
     */
    private static volatile CarHelper1 instance;

    /**
     * 构造方法私有是保证不被外部调用
     */
    private CarHelper1() {
        // 可以根据需求初始化自己需要的内容
    }

    /**
     * 使用双重判断 +  线程锁
     * 双重判断:是为了提升效率,毕竟synchronized算是一个重量级线程锁,如果能在线程锁外面就拦截多线程,则会降低内存消耗
     * 线 程 锁:保证只能有1个线程执行锁内操作
     */
    public static CarHelper1 getInstance() {
        if (instance == null) {
            synchronized (CarHelper1.class) {
                if (instance == null) {
                    instance = new CarHelper1();
                }
            }
        }
        return instance;
    }
}
上一篇下一篇

猜你喜欢

热点阅读