设计模式从入门到放弃(一)单例模式

设计模式从入门到方式(一)单例模式

单例模式

单例模式便是创建型设计模式的一种,单例模式确保某一个类在系统中只有一个实例。

本次使用实现单例模式只列出了线程安全的几种形式

实现步骤

  1. 构造器私有化,防止外部new对象造成多实例.
  2. 内部提供一个static 对象用于保存全局唯一单例的实体
  3. 定义一个静态方法返回该对象

饿汉式

在加载类的时候直接将对象实例,无视是否使用。

  • 优点

    简单 线程安全

  • 缺点

    当类被加载的时候即创建单例对象,如果没有使用该对象会造成内存浪费

public class EagerSingleTon {

    private EagerSingleTon() {
    }

    private static EagerSingleTon INSTANCE = new EagerSingleTon();

    public static EagerSingleTon getInstance() {
        return INSTANCE;
    }

}

懒汉式

双重检查

  • 优点

    线程安全 懒加载 如果没有用到这个单例则不会创建,节省内存

  • 缺点

    实现相对繁琐

public class DoubleCheckSingleTon {
    private  DoubleCheckSingleTon() {
    }

    private static volatile DoubleCheckSingleTon INSTANCE = null;

    public static DoubleCheckSingleTon getINSTANCE() {
        // 多线程首次进入判断INSTANCE 是否为空 如果不为空直接返回
        if (INSTANCE == null) {
            // 多线程同时进入 加锁实例化 其他线程再次进入之后INSTANCE不为空,不会进入第二次if判断
            synchronized (DoubleCheckSingleTon.class) {
                if (INSTANCE == null) {
                    INSTANCE = new DoubleCheckSingleTon();
                }
            }
        }
        return INSTANCE;
    }

}

静态内部类 InstanceHolder

利用Java的类加载机制,外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE,故而不占内存。即当SingleTon第一次被加载时,并不需要去加载SingleTonHolder,但调用getInstance方法才会去实例化对象。

调用getInstance方法会导致Java虚拟机加载InstanceHolder这个静态内部类,在静态内部中实例化外部的对象。

线程安全,实现简单 推荐一种实现方式

public class StaticInnerClassInstanceHolder {

    private StaticInnerClassInstanceHolder() {
    }

    private static class InstanceHolder {
        private static StaticInnerClassInstanceHolder INSTANCE = new StaticInnerClassInstanceHolder();
    }

    public static StaticInnerClassInstanceHolder getInstance() {
        return InstanceHolder.INSTANCE;
    }

}

枚举

枚举单例 枚举在java中与普通类一样,都能拥有字段与方法,而且枚举实例创建是线程安全的,在任何情况下,它都是一个单例。

实现简单 线程安全 推荐使用

public enum EnumSingleTone {

    INSTANCE;

    private String sayHello(String name){
        return "hello" +name;
    }

    public static void main(String[] args) {
        System.out.println(EnumSingleTone.INSTANCE.sayHello("world"));
    }
}

或者这样实现

public class EnumSingleToneDemo {

    private EnumSingleToneDemo() {
        // empty
    }

    private enum Singleton {
        INSTANCE;

        private final EnumSingleToneDemo instance;

        Singleton() {
            // 枚举初始化加载只会执行一次
            this.instance = new EnumSingleToneDemo();
        }

        public EnumSingleToneDemo getInstance() {
            return instance;
        }
    }


    public static EnumSingleToneDemo getInstance() {
        return Singleton.INSTANCE.getInstance();
    }

}

猜你喜欢

转载自blog.csdn.net/woshiwjma956/article/details/105720827