设计模式之单例模式

SPPan 2019-04-09 设计模式 91人已围观

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1 介绍

1.1 主要解决的问题

保证一个类仅有一个实例,并提供一个访问它的全局访问点。从而避免一个全局使用的类频繁地创建与销毁。

1.2 优点

1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销,使用单例模式可以节约系统资源。

2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。

3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。

1.3 缺点

没有接口,不能继承。与单一职责原则冲突。

1.4 使用场景

1、想控制实例数目,节省系统资源的时候。

2、全局只需要一个实例对象,多个会产生多线程问题的时候。

2 实现

1、饿汉模式。

2、饱汉模式。

2.1 饿汉模式

饿汉模式有几个特点:

1、私有化无参构造函数,避免调用者使用new关键字来创建对象。

2、声明静态私有的实例变量,并且直接在类加载的时候实例化。

3、暴露获取实例的方法,但是每次返回的都是同一个实例。

public class SingletonHungry {

    private SingletonHungry() {
    }

    private static SingletonHungry instance = new SingletonHungry();

    public static SingletonHungry getInstance() {
        return instance;
    }

    public void say() {
        System.out.println("SingletonHungry");
    }
}

2.2 懒汉模式

懒汉模式的特点:

1、在第一次使用的时候才对对象进行实例化。

2、需要进行双重检查锁,目的是防止在多线程调用的时候,出现多个实例。

3、成员变量需要使用volatile声明。

public class SingletonLazy {
    private SingletonLazy() {
    }

    private static volatile SingletonLazy instance = null;

    public static SingletonLazy getInstance() {
        if (instance == null) {
            synchronized (SingletonLazy.class) {
                if (instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

    public void say() {
        System.out.println("SingletonLazy");
    }
}

2.3 嵌套类

public class SingletonInner {

    private SingletonInner() {
    }

    private static class Holder {
        private static SingletonInner instance = new SingletonInner();
    }

    public static SingletonInner getInstance() {
        return Holder.instance;
    }

    public void say() {
        System.out.println("SingletonInner");
    }
}

2.4 枚举

枚举类很特殊,它在类加载的时候会初始化里面的所有的实例,而且 JVM 保证了它们不会再被实例化,所以它天生就是单例的。

public enum SingletonEnum {
    instance;

    public void say() {
        System.out.println("SingletonEnum");
    }
}

调用测试

public class Main {
    public static void main(String[] args) {
        SingletonHungry.getInstance().say();
        SingletonLazy.getInstance().say();
        SingletonInner.getInstance().say();
        SingletonEnum.instance.say();
    }
}

吐槽(0)

文章评论

    共有0条评论

文章目录