目录

1. 什么是单例设计模式

2. 单例模式的两种形式

2.1 懒汉式

2.2. 饿汉式

3. 解决懒汉式线程安全问题

4. 懒汉式与饿汉式的区别

5. 单例模式的优点


如果一个类从始至终只能创建一个实例,把这个类就称为单例类。

1. 什么是单例设计模式

单例设计模式就是采取一定的方法保证在整个的软件系统中,对于某个类只能存在一个对象实例 ,并且该类只提供一个得到其对象实例的方法

如果要求类在一个虚拟机中只能产生一个对象,不能自由创建该类的对象。避免其他类创建该类的实例,我们首先必须将类的构造器的访问权限设置为 private ,把该类的构造器隐藏起来了。这样就不能用 new 操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量,也必须用static修饰 。

2. 单例模式的两种形式

2.1 懒汉式

   示例代码:

public class Singleton1 {
    // 提供当前类型的静态变量
    private static Singleton1 s;

    // 构造方法私有化,这样类就不会被实例化
    private Singleton1() {
    }

    // 对外提供一个公开的、静态的方法,获取Singleton1对象
    public static Singleton1 getInstance() {
        // 如果s为null,表明还没有创建Singleton1对象
        // 否则,表明已经创建了对象
        if (s == null) {
            // 创建Singleton1对象
            s = new Singleton1();
        }
        return s;
    }

    public static void main(String[] args) {
        // 创建Singleton1对象不能使用构造器,只能通过getInstance()方法获取实例
        Singleton1 s1 = Singleton1.getInstance();
        Singleton1 s2 = Singleton1.getInstance();

        System.out.println(s1 == s2);
    }

}

代码执行结果:

true

       通过 getInstance() 方法,保证 Singleton1 类只能产生一个对象。因此,代码最后的执行结果是 true,说明 Singleton1 对象实际上是同一个对象。

    懒汉式存在线程安全的问题,在下面将会解决线程安全问题。

2.2. 饿汉式

   示例代码:

public class Singleton2 {
    // 提供当前类型的静态变量
    // 类加载的时候只执行一次
    private static Singleton2 s = new Singleton2();

    // 构造方法私有化
    private Singleton2() {
    }

    // 提供公共的静态的方法,返回当前类的对象
    public static Singleton2 getInstance() {
        return s;
    }

    public static void main(String[] args) {
        // 创建Singleton2对象不能使用构造器,只能通过getInstance()方法获取实例
        Singleton2 s1 = Singleton2.getInstance();
        Singleton2 s2 = Singleton2.getInstance();

        System.out.println(s1 == s2);

    }
}

3. 解决懒汉式线程安全问题

  • 懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能会出现多个Singleton实例。
  • 要实现线程安全,对getInstance()这个方法进行改造,保证了懒汉式单例的线程安全。

   在getInstance()方法上加同步锁

public static synchronized Singleton1 getInstance() {
        if (s == null) {
            s = new Singleton1();
        }
        return s;
    }

4. 懒汉式与饿汉式的区别

饿汉式就是类一旦加载,就会把单例初始化完成。保证getInstance()的时候,单例已经创建好了。

懒汉式比较懒,只有在调用getInstance()的时候,才初始化这个单例。

从这点可以看出,饿汉式天生就是线程安全的,而懒汉式将会出现线程安全的问题。

5. 单例模式的优点

在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:

1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。

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

3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程.。


本文转载:CSDN博客