专业的JAVA编程教程与资源

网站首页 > java教程 正文

带你了解单例模式(Singleton Pattern)的五种写法!

temp10 2024-09-22 10:01:06 java教程 8 ℃ 0 评论

单例模式,是一种常用的软件设计模式。单例模式最初的定义出现于《设计模式》(艾迪生维斯理,1994):"保证一个类仅有一个实例,并提供一个访问它的全局访问点";java中单例模式定义:"一个类有且仅有一个实例,并且自行实例化向整个系统提供"。那么单例模式是何时使用,又是主要解决什么问题呢?优缺点又是什么呢?具体代码怎么实现单例模式呢?那么跟随小编一起,了解单例模式。

带你了解单例模式(Singleton Pattern)的五种写法!

目的:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

主要解决:一个全局使用的类频繁地创建与销毁。

何时使用:当想控制实例数目,节省系统资源的时候。

优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。 2、避免对资源的多重占用。

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

应用实例: 一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。

下面是单例模式的五种写法:

一、懒汉式(线程不安全)

上述代码是存在缺陷的,当有多个线程同时进行的时候,当运行至if(lazySingleton==null)这行代码的时候,另外一个线程也执行到这里的话,就会产生两个对象了。所以上述代码在多线程的情况下是不能运行的。

懒汉式(线程安全)

上述代码用了synchronized关键字,虽然做到了线程安全,但是它的效率并不高。任何时候只能有一个线程获取到实例,但是同步操作只需要第一次调用的时候才被需要。那么如何改进呢?双重检验锁很好的解决了这个问题。

二、双重检验锁

代码如下:

双重检验锁模式我们又称其为双重检查锁。如上述代码所示,一次是在同步块外,一次是在同步块内。如果多个线程同时进入同步块外的if,同步块内不进行二次检验也会产生多个实例,这也是为什么要检验两次的原因。

三、饿汉式

这种方式很简单,因为已经被声明成static和final了,第一次加载类已经完成初始化了,并且本身也是线程安全的。

上述代码实现简单,并且线程安全,那么它是否是完美的呢?并不是!因为它在一开始就被初始化,在一些场景中并不适用,比如我们要获取的实例是要依赖配置文件的,在获取该实例之前我们想要给它设置参数,是实现不了的。

四、静态内部类

上述代码由于类Singleton是私有的,只有getSingleton()能访问到它,所以它也是懒汉式。线程安全,没有性能缺陷。

五、枚举

创建枚举本身就默认线程安全的,还能防止反序列化重新创建新的对象。就是这么简单!

那么我们平时用哪种方式呢?依我看还是根据实际需要。一般情况下饿汉式就可以了。如果对懒加载有要求,可以考虑内部类方式。如果涉及到反序列化创建对象试着使用枚举的方式来实现。

大家可以记住实现单例的核心:两私一公。即私有对象创建,私有的构造方法和一个对外公共访问点。记住这一点,再理解好多了。

每天学习一点点,不积跬步,无以至千里;不积小流,无以成江海!最后祝大家工作顺利,每天开开心心!!!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表