Singleton模式及常见问题

本文详细介绍了Singleton模式的概念、实现方式及其在多线程环境下的注意事项。探讨了如何避免多线程下实例重复创建的问题,并提供了几种不同的解决方案。

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

1. Singleton模式介绍:

Singleton模式也成为单件模式,即确保一个类只有一个实例,并提供一个全局的访问点.

类图:

Singleton

Static instance

//其他有用的单件数据

Static getInstance()

//其他有用的单件方法


2. Singleton模式的实现:

public class SingletonMethod {

private static SingletonMethod instance = null;



private SingletonMethod(){



}



public static SingletonMethod getInstance() {

if (null == instance) {

instance = new SingletonMethod2();

}

return instance;

}



/**

* @param args

*/

public static void main(String[] args) {

SingletonMethod test1= SingletonMethod.getInstance();

SingletonMethod test2= SingletonMethod.getInstance();;

System.out.println(test1.equals(test2));

System.out.println(test1.hashCode()==test2.hashCode());

}



}

实现的说明;构造器是私有的,保证不能被外部类所直接创建.在通过getInstance()来调用时,判断实例是否已经创建,如果没有创建再进行创建.通过测试我们验证了创建2次出的实例确实时一个.真的很简单.那我们还是来看看下面的注意事项吧!

3. Singleton模式的注意事项

上面的实现好像很好,不过上面的做法却不能保障我们每次取到的实例就是一个,那么是什么时候呢?让我们来看看.当我们程序中使用了多线程的时候,确实有创建了两个不同实例的时候,究竟是为什么呢?研究发现,其实有时候会有两个线程同时去访问getInstance(),发现instance为null,那么他们都会去创建这个实例并返回,这样就会产生两个实例了.哈哈,问题找到了,我们要怎么来修改呢?

首先我们想到的是,多线程并发时我们可以使用synchronized的,我们这样来修改一下:

public static synchronized SingletonMethod2 getInstance() {

if (null == instance) {

instance = new SingletonMethod2();

}

return instance;

}

问题得到解决了,可以仔细考虑时我们发现,还有一个比较严重的问题,只有第一次执行此方法才需要同步,那么我们每次都来同步它,一定会降低效率的.如果您能接收这样的处理负担,那么这样的方法还是很好的,简单有效.

那么有办法改善多线程嘛?参见以下处理方法:

1. 使用”急切”创建实例,二不用延迟实例化的做法

public class SingletonTest {

private SingletonTest() {

}

private static SingletonTest instance = new SingletonTest();

public static SingletonTest getInstance() {

return instance;

}

public static void main(String[] args) {

SingletonTest test1= SingletonTest.getInstance();

SingletonTest test2= SingletonTest.getInstance();;

System.out.println(test1.equals(test2));

System.out.println(test1.hashCode()==test2.hashCode());

}

}

2. 使用”双重加锁”的办法

private volatile static SingletonMethod2 instance = null;



public static SingletonMethod2 getInstance() {

if (null == instance) {

synchronized (SingletonMethod2.class) {

if (null == instance) {

instance = new SingletonMethod2();

}

}



}

return instance;

}

Volatile 关键字确保,当instance变量被初始化为singleton实例时,多个线程能正确地处理instance变量.

注:双重加锁不适用于1.4及更早的JDK.

总结一些吧:其实大多数人都了解singleton模式,在使用的过程中也都用过,不过你们注意了这些可能的问题了嘛?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值