200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 单例模式(懒汉模式-双检锁 饿汉模式 静态内部类模式)-详细

单例模式(懒汉模式-双检锁 饿汉模式 静态内部类模式)-详细

时间:2020-03-26 19:52:01

相关推荐

单例模式(懒汉模式-双检锁 饿汉模式 静态内部类模式)-详细

文章目录

前言单例模式(懒汉模式-双检锁、饿汉模式、静态内部类模式)-详细01 单例模式是什么?02 单例模式的好处?03 单例模式的三种模式03::01 懒汉模式03::01::01 问:为什么不在方法上加锁,而是在方法内部加锁?03::01::02 问:单例类对象前面为什么要加volatile 关键字03::02 饿汉模式03::03 静态内部类模式03::04 总结

前言

如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。

而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


单例模式(懒汉模式-双检锁、饿汉模式、静态内部类模式)-详细

01 单例模式是什么?

单例模式即每一个类都有一个实例

使用场景:线程池、链接池。

02 单例模式的好处?

java 中单例模式带来两个好处:

1.对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级的对象而言,是非常可观的一笔系统开销。

2.由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。

03 单例模式的三种模式

1、懒汉模式

2、饿汉模式

3、静态内部类

注:推荐使用静态内部类模式使用单例。

03::01 懒汉模式

实现步骤:

1、构造函数私有化–防止外面直接调用;

2、制作一个返回单例方法;

3、实现一个单例类对象 ,并在前面加上volatile;

4、判断-如果该单例对象为空,实例化一个对象(第一次检查);

5、为了防止多线程场景下多个线程同时访问,多次初始化单例类对象,初始化实例对象前加一把锁;

6、为了防止多线程场景下多个线程第一个检查校验过去,走下面的锁竞争后,依次创建实例,违反单例原则, 而在加一次检查的目的是只有为空的时候创建单例对象(第二次检查);

7、!= null 直接返回;

这就是饿汉模式-双检锁。

实例:

class LanSingleton{private volatile static LanSingleton instance;//private LanSingleton(){}public static LanSingleton getInstance(){if (instance == null){synchronized (LanSingleton.class){if (instance == null){instance = new LanSingleton();}}}return instance;}}

测试:

/*** @description: TODO 懒汉模式-双检锁* @author 杨镇宇* @date /2/28 15:08* @version 1.0*/public class LanSingletonTest {public static void main(String[] args) {new Thread(()->{System.out.println(LanSingleton.getInstance());}).start();new Thread(()->{System.out.println(LanSingleton.getInstance());}).start();}}

效果:

03::01::01 问:为什么不在方法上加锁,而是在方法内部加锁?

因为直接在方法上加锁,相当于每次线程调用过来都要等上一个线程执行完毕,实际消耗时间太大。

03::01::02 问:单例类对象前面为什么要加volatile 关键字

JVM加载会有重排序的问题,因为CPU为了加载执行速度,会根据自己的优化策略,有些代码会进行优化,即重排序, * 而volatile有防止重排序的特点。


03::02 饿汉模式

特点:立即加载就会使用类,使用类加载机制保障单例模式,因为类加载的时候静态变量就已经加载成功。

实例:

class ESingleton{private static final ESingleton instance = new ESingleton();private ESingleton(){}public static ESingleton getInstance(){return instance;}}

测试:

/*** @description: TODO 饿汉模式 立即加载就会使用类,给予类加载机制保障单例模式* @author 杨镇宇* @date /2/28 15:40* @version 1.0*/public class ESingletonTest {public static void main(String[] args) {new Thread(()->{System.out.println(ESingleton.getInstance());}).start();new Thread(()->{System.out.println(ESingleton.getInstance());}).start();}}

效果:


03::03 静态内部类模式

特点: 静态内部类也是给予类加载机制保证单例模式。

实例:

class ClassSingleton{private static class InnerClassSingletonHolder{private static ClassSingleton instance = new ClassSingleton();}private ClassSingleton(){}public static ClassSingleton getInstance(){return InnerClassSingletonHolder.instance;}}

测试:

/*** @description: TODO 静态内部类 给予类加载机制保障单例模式* @author 杨镇宇* @date /2/28 15:59* @version 1.0*/public class ClassSingletonTest {public static void main(String[] args) {new Thread(()->{System.out.println(ClassSingleton.getInstance());}).start();new Thread(()->{System.out.println(ClassSingleton.getInstance());}).start();}}

效果:


03::04 总结

对于静态内部类模式来说,保证线程安全的前提下,有点懒汉模式的味道,即不调用这个getInstance方法时,就不会加载这个类InnerClassSingletonHolder,也就不会浪费空间,而饿汉模式,就会马上加载,会浪费空间,但是它保证单例模式跟饿汉模式一样都是给予JVM的类加载机制保证单例模式,所以有点兼容懒汉模式和饿汉模式的味道,因此使用的话,推荐使用静态内部类模式来写单例模式。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。