单例设计模式


单例设计模式是什么?

单例设计模式是应用最广泛的设计模式,没有之一。当我们需要控制一个类只能被创建出单个对象时,就可以采用单例设计模式。 使用java来实现单例设计模式,普遍有四种实现方式。

  • 懒汉式
  • 饿汉式
  • 双检锁(double check)
  • innerclass holder

单例设计模式怎么用?

懒汉式

懒汉式是最常见的单例设计模式的实现方式之一。懒汉代表的含义为lazy-load,意味着当单例对象在项目中,真正被某个业务模块使用时,对象才会被创建。

package com.designpattern.singleton;

/**
 * 单例设计模式-懒汉式
 */
public class SingletonLazyMode {


    private static SingletonLazyMode shm;

    /**
     * 私有化构造器
     */
    private SingletonLazyMode() {

    }

    /**
     * 获取单例
     * 面临并发安全问题,可能会创建多个实例
     * 需要对方法进行同步.(独占锁)
     *
     * @return obj
     */
    public static synchronized SingletonLazyMode getSingleton() {
        // 在判断处可能发生并发安全问题.
        if (shm != null) {
            return shm;
        } else {
            shm = new SingletonLazyMode();
            return shm;
        }
    }

}

懒汉式面临的问题: getSingleton方法中,判断引用是否为空的逻辑可能发生并发安全问题,可能会创建出复数个对象。

饿汉式

饿汉式与懒汉式刚好是一对反例。一旦饿汉式的class被加载且进行初始化后,单例对象就会被马上创建。

package com.designpattern.singleton;

/**
 * 单例设计模式-饿汉式
 */
public class SingletonHungryMode {


    private static SingletonHungryMode shm = new SingletonHungryMode();


    // 构造器
    private SingletonHungryMode() {


    }

    /**
     * 返回实例对象
     * 饿汉式避免了并发安全问题,但是却无法实现lazyLoad
     *
     * @return
     */
    public static SingletonHungryMode getSingleton() {
        return shm;
    }

}

饿汉式面临的问题: 对象无法实现lazy-load。当类被反射调用或设置读取类的静态字段以及执行某个静态方法时,类的静态成员变量就会被初始化。

双检锁

为了解决懒汉式的并发安全问题,又为了减少独占锁而设计出来的一种单例实现方式。

暂无内容

innerclass holder

配合静态内部类实现的单例模式。即使外部类的任何成员被访问,持有外部类单例对象的内部类,直到getInstance方法被调用为止,都不会被初始化。 这种模式即实现了lazy-load,又避免了普通懒汉式的并发安全问题。

package com.designpattern.singleton;

/**
 * 单例设计模式-innerclass holder
 */
public class SingletonInnerMode {


    /**
     * 私有化构造器
     */
    private SingletonInnerMode() {

    }


    /**
     * 持有外部类对象的引用.
     * 每次被初始化后,sim只会被加载一次.
     */
    private static class SingletonInnerHolder {

        private static SingletonInnerMode sim = new SingletonInnerMode();

        /**
         * 私有化构造器
         */
        private SingletonInnerHolder() {

        }

    }

    /**
     * 获取单例对象.
     * getInstance被调用时候,内部类才会被加载
     *
     * @return
     */
    public static SingletonInnerMode getInstanse() {
        // 访问成员变量时,内部类的静态成员变量才被初始化
        return SingletonInnerHolder.sim;
    }

}

总结

  1. 单例设计模式运用很广泛。
  2. 在大多数项目中,如果你对性能不是要求特别苛刻,饿汉式可以满足我们的需求。
  3. 如果你喜欢lazy-load,那么普通的懒汉式在大部分项目中也完全够用。
  4. innerclass holder实现很巧妙,如果你的某个类在初始化时会进行大量运算,则推荐使用它来解决问题。

Copyright 2017/08/15 by Chuck Lin

若文章有幸帮到了您,您可以捐助我,以鼓励我写出更棒的作品!

alipay.jpg-17.7kBwechat.jpg-16.7kB

Copyright © chuck Lin 2017 all right reserved,powered by Gitbook该文件修订时间: 2019-01-25 03:17:41

results matching ""

    No results matching ""