单件模式中多线程情况下重复创建对象问题的三种处理办法

本文探讨了在单例模式中遇到多线程环境下可能导致对象重复创建的问题,提出了三种处理方法:1) 使用`synchronized`关键字同步方法,但可能降低性能;2) 前置实例化,即使对象可能未被使用;3) 双重检查锁定(double-checked locking),配合`volatile`关键字确保线程安全。需要注意的是,双重检查锁定在Java 1.4及以下版本可能存在问题,应使用Java 5及以上版本。此外,类加载器和垃圾收集器在不同场景下的行为也可能影响单例模式的实现,需要谨慎处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

1、利用synchronize关键字

public class Singleton {

    private static Singleton uniqueInstance;

    public static synchronize Singleton getInstance() {

        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

缺点:会降低性能,同步一个方法可能造成程序执行效率下降100倍。

 

 

2、迫切的创建实例,哪怕你用不到它,而不是用延迟实例化

public class Singleton {

    private static Singleton uniqueInstance = new Singleton();

    public static Singleton getInstance() {

        return uniqueInstance;
    }
}

缺点:对新建一个用不到的对象也无所谓。

 

 

3、使用双重加锁(double-checked locking),保证getInstacne()只在第一次会使用同步

public class Singleton {

    private volatile static Singleton uniqueInstance;

    public static Singleton getInstance() {

        if (uniqueInstacne == null) {

            synchronized (Singleton.class) {

                if (uniqueInstance == null) {

                    uniqueInstance = new Singleton();

                }
            }
        }
        return uniqueInstance;
    }
}

 

volatile关键子确保当uniqueInstance变量被初始化成Singleton实例时,多个线程正确的处理uniqueInstance变量(volatile保证了共享变量的可见性,一个线程对变量的操作其他线程会立马知晓,所以不会出现还未初始化完成就被使用的情况)

 

缺点:Java 1.4中许多JVM虚拟机对于volatile关键字的实现会导致双重检查加锁失败,所以只能使用Java5或以上的版本

 

 

tips:有个要注意的地方,关于类加载器的,因为每个类加载器都定义了一个命名空间,如果有两个以上的类加载器,不同的类加载器可能会加载同一个类,从整个程序来看,同一个类会被加载多次。如果这样的事情发生在单件上,就会产生多个单件并存的怪异现象,所以,如果你的程序有多个类加载器同时又使用了单件模式,请格外小心。有一个解决办法:自行指定类加载器,并指定同一个类加载器。

tips2:在Java 1.2之前,垃圾收集器有个bug:当单件在没有全局引用时会被当做垃圾被清除,也就是说,如果一个单件只有本单件类引用它本身,那么该单件就会被当做垃圾清除。这造成让人困惑的bug,因为在单件被清除之后,下次调用getInstance()会产生一个“全新的”单件。对很多程序来说,这会造成让人困惑的行为,因为对象的实例变量值都不见了,一切回到原始的设置(例如:网络连接被重新设置)。但是在Java 1.2以后,这个bug已经被修正了,也不再需要一个全局引用来保护单件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值