首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >单例模式 java 三种写法_双重锁的单例模式

单例模式 java 三种写法_双重锁的单例模式

作者头像
全栈程序员站长
发布2022-09-22 15:04:16
发布2022-09-22 15:04:16
53100
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

单例模式有多种写法,都有各自的优缺点,最常见的优缺点就是【懒汉和饿汉】的比较,以及是否线程安全

  • 懒汉模式,节约内存,只有使用到时才创建单例对象,可能会有线程安全问题
  • 饿汉模式,浪费内存,但可以由JVM类加载器去保证线程安全

一、饿汉模式

代码语言:javascript
代码运行次数:0
运行
复制
public class Singleton1 { 
   

    /** * 饿汉式提前创建好单例对象(在类被主动使用时便会触发静态变量的初始化) */
    private final static Singleton1 INSTANCE = new Singleton1();

    /** * 禁止外部实例化 */
    private Singleton1() { 
   

    }

    public static Singleton1 getInstance() { 
   
        return INSTANCE;
    }
}

二、懒汉模式(线程不安全)

代码语言:javascript
代码运行次数:0
运行
复制
public class Singleton2 { 
   

    /** * 即使是类被主动使用,也不会触发INSTANCE的创建 */
    private static volatile Singleton2 INSTANCE = null;

    /** * 禁止外部实例化 */
    private Singleton2() { 
   

    }

    /** * 当调用getInstance方法获取单例对象时再创建单例对象,当INSTANCE为空时才创建 * 这种是线程不安全的 */
    public static Singleton2 getInstance() { 
   
        if (INSTANCE == null) { 
   
            INSTANCE = new Singleton2();
        }
        return INSTANCE;
    }
}

三、懒汉模式(线程安全)

代码语言:javascript
代码运行次数:0
运行
复制
public class Singleton6 { 
   

    private static volatile Singleton6 INSTANCE = null;

    /** * 禁止外部实例化 */
    private Singleton6() { 
   

    }

    public static Singleton6 getInstance() { 
   
      	// 通过加锁保证线程安全,但是性能会相应的降低
        synchronized (Singleton6.class) { 
   
            if (INSTANCE == null) { 
   
                INSTANCE = new Singleton6();
            }
            return INSTANCE;
        }
    }

}

四、双检锁单例

代码语言:javascript
代码运行次数:0
运行
复制
public class Singleton3 { 
   

    /** * 注意这里需要用volatile去修饰,以避免指令重排代理的多线程安全问题 */
    private static volatile Singleton3 INSTANCE = null;

    /** * 禁止外部实例化 */
    private Singleton3() { 
   

    }

    public static Singleton3 getInstance() { 
   
        // 两次检查,线程安全
        if (INSTANCE == null) { 
   
            synchronized (Singleton3.class) { 
   
                if (INSTANCE == null) { 
   
                    INSTANCE = new Singleton3();
                }
            }
        }
        return INSTANCE;
    }

}

五、静态内部类写法

代码语言:javascript
代码运行次数:0
运行
复制
public class Singleton4 { 
   

    /** * 禁止外部实例化 */
    private Singleton4() { 
   

    }

    public static Singleton4 getInstance() { 
   
        // 外部内可以访问静态内部类的私有成员变量
        return Holder.instance;
    }

    /** * 静态内部类实现单例模式,只有在Holder类被主动使用时才会触发Holder类的加载,从而触发instance的实例化, * 并且是由JVM去实例化的保证线程安全,所以这种模式也是线程安全的懒汉模式 */
    static class Holder { 
   
        /** * 静态内部类里持有一个Singleton4的单例对象 */
        private static Singleton4 instance = new Singleton4();
    }
}

六、枚举写法

代码语言:javascript
代码运行次数:0
运行
复制
public enum Singleton5 { 
   

    /** * 单例对象,枚举实现单例,写法就很简单了,并且能保证线程安全(枚举类是由JVM加载),但枚举是饿汉模式 */
    INSTANCE;

    /** * 提供一个获取枚举对象的方法 */
    public Singleton5 getInstance() { 
   
        return INSTANCE;
    }
}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/169700.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、饿汉模式
  • 二、懒汉模式(线程不安全)
  • 三、懒汉模式(线程安全)
  • 四、双检锁单例
  • 五、静态内部类写法
  • 六、枚举写法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档