Java多线程编程核心技术 —— 单例模式与多线程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lkp1603645756/article/details/84861702

1、立即加载 / “饿汉模式”,立即记载就是使用类的时候已经将对象创建完毕,常见的实现方法就是直接new 实例化。而立即加载从中文的语境来看,有“着急”、“急迫”的含义,所以也称“饿汉模式”。立即加载 / “饿汉模式”是在调用方法前,实例已经被创建了。

2、延迟加载 / “懒汉模式”,延迟加载就是在调用get()方法时实例才被创建,常见的实现方法就是在get()方法中进行new 实例化。而延迟加载从中文的语境来看,是“缓慢”、“不急迫”的含义,所以也称为“懒汉模式”。

3、使用懒汉模式的时候,有个问题需要注意,再多线程情况下,得到的不是同一个实例对象的问题,效率最高的解决方案是:

使用DCL双检查锁机制,使用该机制来实现多线程环境中的延迟加载单例设计模式。

此版本的代码称为双重检查Double-Check Locking

使用双重检查锁功能,成功地解决了“懒汉模式”遇到多线程的问题。DCL也是大多数多线程结合单例模式使用的解决方案。

4、DCL可以解决多线程单例模式的非线程安全问题。当前,使用其他的方法也能达到同样的效果,比如使用静态内置类实现单例模式。

静态内置类的优点:

1)加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。

2)同一个加载器下,一个类型只会初始化一次。

3) 虚拟机会保证一个类初始化的时候,在多线程环境中被正确地加锁、同步

所以说静态内部类形式的单例可保证线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。

5、静态内置类可以达到线程安全问题,但如果遇到序列化对象时,使用默认的方式运行得到的结果还是多例的。

解决方法就是在反序列化中使用readResolve()方法。

6、静态代码块中的代码在使用类的时候就已经执行了,所以可以应用静态代码块的这个特性来实现单例设计模式。

什么是静态块呢?

1)它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的;

2)静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的;

3)静态代码块中的变量是局部变量,与普通函数中的局部变量性质没有区别;

4)一个类中可以有多个静态代码块;

类中函数的执行顺序分别为:

1)静态代码块

2)main 函数

3)构造代码块

4)构造函数

利用静态代码块只在类加载的时候执行,并且只执行一次这个特性,也可以用来实现单例模式,但是不是懒加载,也就是说每次类加载就会主动触发实例化。

除此之外,不考虑单例的情况,利用静态代码块的这个特性,可以实现其他的一些功能,例如上面提到的配置文件加载的功能,可以在类加载的时候就读取配置文件的内容,相当于一个预加载的功能,在使用的时候可以直接拿来就用。

7、使用enum枚举数据类型实现单例模式。枚举enum和静态代码块的特性相似,在使用枚举类时,构造方法会被自动调用,也可以应用其这个特性实现单例设计模式。

使用枚举实现单例模式的时候,切记不可暴露枚举类,这样就违反了“职责单一原则”。

左侧有我的公众号二维码,微信扫一扫即可关注,每天都会分享技术文章,一起成长。

如果有错误的地方,还请不吝赐教,非常感谢~


欢迎访问我的CSDN博客,让我们一同成长!

“不管做什么,只要坚持下去就会看到不一样!”

猜你喜欢

转载自blog.csdn.net/lkp1603645756/article/details/84861702