温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java单例模式实例分析

发布时间:2022-01-05 15:10:06 来源:亿速云 阅读:138 作者:iii 栏目:大数据

这篇文章主要介绍“java单例模式实例分析”,在日常操作中,相信很多人在java单例模式实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java单例模式实例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

在早期的项目代码中,如果我们想使用类的某个方法,我们基本都会创建一个类的对象实例然后再调用方法,这样的实现往往在系统内就会存在某个类的大量实例。如此一来,项目框架很难管理大量的对象,而且如果java虚拟机不能及时回收,容易造成内存溢出。

首先我们要明白什么是单例,所谓单例就是说在项目框架内某个类的对象实例只存在一个,任何调用方获取到的对象实例都是一个,那么很明显这个类是不能够被外部直接调用类构造器创建的。

我们先看下一个简单的单例设计:

java单例模式实例分析

上面代码在单线程是没有问题的,而且只有当线程调用类的静态方法时,才会生成类的静态变量。但是当多线程访问时,上面代码是有问题的,会生成多个对象的实例。

那么,我们可以用另外一种方法实现,比如说在类加载时候就初始化对象的实例,这样后面无论怎么调用类静态方法都不创建新的实例。还有一种方法,但是会牺牲部分系统性能,意思就是在多线程访问方法时通过锁机制让线程排队访问。我们先通过在类方法上加锁来实现类的单例,比如:

java单例模式实例分析

上述方法能实现单例,而且采用的思路是延迟加载,但是执行效率比较低。

之前有看到部分同学使用双重锁(Double CheckLock)机制来实现单例模式,一方面需要在实例上加上volatile关键字通知操作系统实现线程访问时内存屏障,然后还需要在方法中通过虚拟机实现的synchronized来同步方法访问,写法如下:

java单例模式实例分析

反正,我认为上面的实现是比较复杂的,大家需要去了解的知识点比较多,比如volatile ,synchronized,内存屏障。因此我不建议大家用这种方式,可以作为技术了解下还是有好处的,毕竟如果能跟面试官探讨到这一步,还是会加一些分的。

如果说我们不考虑服务负载问题,在多线程环境下可以预先加载类的静态实例,当虚拟机加载完成类后就会创建类的静态变量,甭管你到时用不用,反正给你留在那里。所有线程访问到的都是同一静态实例,有人也称这种方式为饿汉式,具体写法如下:

java单例模式实例分析

上面写法实现单例也是没有问题的,但是有些同学就会觉得如果我只是想调用一个类的某个静态方法,并不想生成它的实例,那有没有其他方法呢,经过各路大神的指点结合自身的总结,可以使用内部静态类来实现这个需求。

开发的同学都知道,虚拟机在加载类的过程中一开始并不会初始化类的内部静态类。如果线程调用内部静态类时,虚拟机只会初始化一次,这样既可以实现单例,同时也是线程安全的。具体写法如下:

java单例模式实例分析

除了以上讲到的几种方式外,JDK自身的枚举类型本身就是单例的实现,调用者不能显式的调用构造器完成实例创建,因此很多Java规范文档推荐使用枚举来实现单例。

当然对于初级开发人员而言,现在的主流开发框架都提供单例/多例模式供开发者选择,这样的好处让开发者更多关注业务功能开发,而不用过多关注虚拟机内部类实例创建问题。例如spring中默认类注入就是单例的,可以根据实际情况设置scope为singleton(单例)或者prototype(多例),如下图所示:

java单例模式实例分析

到此,关于“java单例模式实例分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI