饿汉式,线程安全

    • 是否 Lazy 初始化:否
    • 是否多线程安全:是

    • 描述:这种方式比较常用,但容易产生垃圾对象。

    • 优点:没有加锁,执行效率会提高。
    • 缺点:类加载时就初始化,浪费内存。

    它基于 classloader 机制避免了多线程的同步问题。
    ```java public class SingleObject { //创建 SingleObject 的一个对象 private final static SingleObject INSTANCE = new SingleObject();

    1. //让构造函数为 private,这样该类就不会被实例化
    2. private SingleObject() {
    3. }
    4. //获取唯一可用的对象
    5. public static SingleObject getInstance() {
    6. return INSTANCE;
    7. }

    }

    1. <br />**<br />**懒汉式,线程安全**
    2. - 是否 Lazy 初始化:是
    3. - 是否多线程安全:是
    4. - 描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
    5. - 优点:第一次调用才初始化,避免内存浪费。
    6. - 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。(该方法使用不太频繁)。
    7. ```java
    8. public class SingleObject {
    9. private static SingleObject instance;
    10. private SingleObject() {
    11. }
    12. public static synchronized SingleObject getInstance() {
    13. if (instance == null) {
    14. instance = new SingleObject();
    15. }
    16. return instance;
    17. }
    18. }

    双检锁/双重校验锁(DCL,即 double-checked locking)

    • 是否 Lazy 初始化:是
    • 是否多线程安全:是

    • 描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。getInstance() 的性能对应用程序很关键。

    1. public class SingleObject {
    2. private static volatile SingleObject instance;
    3. private SingleObject() {
    4. }
    5. public static SingleObject getInstance() {
    6. if (instance == null) {
    7. synchronized (SingleObject.class) {
    8. if (instance == null) {
    9. instance = new SingleObject();
    10. }
    11. }
    12. }
    13. return instance;
    14. }
    15. }



    静态内部类**

    • 是否 Lazy 初始化:是
    • 是否多线程安全:是

    这种方式同样利用了 classloader 机制来保证初始化 instance 时只有一个线程。这种方式是 SingleObject 类被装载了,instance 没有被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance()方法时,才会显式装载 SingletonHolder 类,从而实例化 instance

    1. public class SingleObject {
    2. private static class SingletonHolder {
    3. private static final SingleObject INSTANCE = new SingleObject();
    4. }
    5. private SingleObject (){}
    6. public static final SingleObject getInstance() {
    7. return SingletonHolder.INSTANCE;
    8. }
    9. }


    枚举**

    • 是否 Lazy 初始化:否
    • 是否多线程安全:是
    • 描述:这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
      1. public enum SingleObject {
      2. INSTANCE;
      3. }