DesignPattern系列__10单例模式

单例模式介绍

单例模式,是为了确保在整个软件体统中,某个类对象只有一个实例,并且该类通常会提供一个对外获取该实例的public方法(静态方法)。
比如日志、数据库连接池等对象,通常需要且只需要一个实例对象,这就会使用单例模式。

单例模式的八种模式

  • 饿汉式(静态常量)
  • 饿汉式(静态代码块)
  • 懒汉式(线程不安全)
  • 懒汉式(同步方法)
  • 懒汉式(同步代码块)
  • 懒汉式(双重检查)
  • 静态内部类
  • 枚举

下面依次来说明一下:

饿汉式(静态常量)

通常,我们创建一个对象的方式就是new,但是,当我们考虑只创建一个实例的时候,就应该禁止外部来通过new的方式进行创建。同时,由于无法使用new,你应该考虑提供一个获取单例对象的方式给别人。

思路

1.将构造器私有化(防止外部new,但是对反射还是有局限)
2.类的内部创建对象
3.对外提供一个获取实例静态的public方法

代码实现如下:

public class Singleton1 {
    public static void main(String[] args) {
        HungrySingleton hungrySingleton = HungrySingleton.getInstance();
        HungrySingleton hungrySingleton1 = HungrySingleton.getInstance();
        System.out.println(hungrySingleton == hungrySingleton1);
    }
}

class HungrySingleton {
    //1.私有化构造器
    private HungrySingleton() {
    }

    // 2.类内部创建对象,因为步骤3是static的,
    // 该方法也是static的
    private static HungrySingleton instance = new HungrySingleton();

    //3.对外提供一个获取对象的方法,
    // 因为调用方式的目的就是为了获取对象,
    // 所以该方法应该是static的。
    public static HungrySingleton getInstance() {
        return instance;
    }
}

运行程序显示,我们的确只创建了一个对象实例。

小结

优点:代码实现比较简单,在类加载的时候就完成了实例化,同时,该方式能够避免线程安全问题。
缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
这种方式基于classloder机制避免了多线程的同步问题,不过, instance在类装载时就实例化,在单例模式中大多数都是调用getInstance方法, 但是导致类装载的原因有很多种, 因此不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance就没有达到lazy loading的效果。

猜你喜欢

转载自www.cnblogs.com/JackHou/p/11316092.html