java中如何正确创建一个单例类实例

本文深入探讨了Java中的单例模式实现,包括饿汉模式和不同类型的双检锁实现,分析了它们的线程安全性、性能影响及可能存在的问题。通过对比,展示了如何确保在整个JVM生命周期中只存在一个类实例,并重点介绍了使用双重检查锁来避免并发问题和防止多次实例化。
摘要由CSDN通过智能技术生成

单例模式

单例模式是指,在整个jvm生命周期中,让一个类只有一个实例存在,类只实例化一次。所有的代码共享这一个实例。

单实例创建-饿汉模式

利用jvm在加载类时,线程安全的,保证类加载完毕,实例创建完毕,只创建一次

public class VillianSingletonTest {
    private VillianSingletonTest() {
    }

    private static final VillianSingletonTest INSTANCE = new VillianSingletonTest();

    public static VillianSingletonTest getInstance() {
        return INSTANCE;
    }

}

单实例创建-多种创建方法比较

  private static MultiSingletonCreateTest INSTANCE;

    private MultiSingletonCreateTest() {
    }

    public static void main(String[] args) {

    }

    /**实例1,存在问题:线程不安全,不能保证整个jvm中只有DclLockTest一个实例,
     * 还有半初始化问题,
     * 比如两个线程同时执行:INSTANCE = new DclLockTest();这行代码
     */
    public static MultiSingletonCreateTest getInstance1() {
        if (INSTANCE == null) {
            //其他逻辑
            INSTANCE = new MultiSingletonCreateTest();
            //其他逻辑
            return INSTANCE;
        }
        return INSTANCE;
    }
    /**实例2,存在问题:虽然能够保证线程安全,但是影响程序并发度,损失性能
     *
     */
    public static synchronized MultiSingletonCreateTest getInstance2() {
        if (INSTANCE == null) {
            INSTANCE = new MultiSingletonCreateTest();
            return INSTANCE;
        }
        return INSTANCE;
    }
    /**实例3,存在问题:虽然不会同时创建实例,但是还是会重复创建实例,
     * 如两个线程同时加锁,后加锁成功的线程,也会创建实例
     *
     */
    public static  MultiSingletonCreateTest getInstance3() {
        if (INSTANCE == null) {
            synchronized(DclLockTest.class){
                INSTANCE = new MultiSingletonCreateTest();
            }
            return INSTANCE;
        }
        return INSTANCE;
    }
    /**实例4,存在问题:会出现INSTANCE半初始化的问题,
     *INSTANCE = new DclLockTest();这行代码,编译成class文件,
     * 会形成三条jvm指令,1:分配内存,2:初始化,3:变量赋值,
     * 若jvm将这三条指令重排序,1->3->2,另外的线程使用未初始化的变量,
     * 程序执行结果可能不是预期的,发生错误
     */
    public static  MultiSingletonCreateTest getInstance4() {
        if (INSTANCE == null) {
            synchronized(MultiSingletonCreateTest.class){
                if(INSTANCE == null){
                    INSTANCE = new MultiSingletonCreateTest();
                }
            }
            return INSTANCE;
        }
        return INSTANCE;
    }

单实例创建-双重检查锁

public class DclLockTest {
    private static volatile DclLockTest INSTANCE;

    private DclLockTest() {
    }

    public static void main(String[] args) {

    }

    /**完美,双重检查+锁+volatile变量,volatile变量,
     * 禁止jvm重排序
     *
     */
    public static  DclLockTest getInstance5() {
        if (INSTANCE == null) {
            synchronized(DclLockTest.class){
                if(INSTANCE == null){
                    INSTANCE = new DclLockTest();
                }
            }
            return INSTANCE;
        }
        return INSTANCE;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值