java单例模式实例分析
这篇文章主要介绍“java单例模式实例分析”,在日常操作中,相信很多人在java单例模式实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java单例模式实例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
十余年的志丹网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。营销型网站的优势是能够根据用户设备显示端的尺寸不同,自动调整志丹建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“志丹网站设计”,“志丹网站推广”以来,每个客户项目都认真落实执行。
在早期的项目代码中,如果我们想使用类的某个方法,我们基本都会创建一个类的对象实例然后再调用方法,这样的实现往往在系统内就会存在某个类的大量实例。如此一来,项目框架很难管理大量的对象,而且如果java虚拟机不能及时回收,容易造成内存溢出。
首先我们要明白什么是单例,所谓单例就是说在项目框架内某个类的对象实例只存在一个,任何调用方获取到的对象实例都是一个,那么很明显这个类是不能够被外部直接调用类构造器创建的。
我们先看下一个简单的单例设计:
上面代码在单线程是没有问题的,而且只有当线程调用类的静态方法时,才会生成类的静态变量。但是当多线程访问时,上面代码是有问题的,会生成多个对象的实例。
那么,我们可以用另外一种方法实现,比如说在类加载时候就初始化对象的实例,这样后面无论怎么调用类静态方法都不创建新的实例。还有一种方法,但是会牺牲部分系统性能,意思就是在多线程访问方法时通过锁机制让线程排队访问。我们先通过在类方法上加锁来实现类的单例,比如:
上述方法能实现单例,而且采用的思路是延迟加载,但是执行效率比较低。
之前有看到部分同学使用双重锁(Double CheckLock)机制来实现单例模式,一方面需要在实例上加上volatile关键字通知操作系统实现线程访问时内存屏障,然后还需要在方法中通过虚拟机实现的synchronized来同步方法访问,写法如下:
反正,我认为上面的实现是比较复杂的,大家需要去了解的知识点比较多,比如volatile ,synchronized,内存屏障。因此我不建议大家用这种方式,可以作为技术了解下还是有好处的,毕竟如果能跟面试官探讨到这一步,还是会加一些分的。
如果说我们不考虑服务负载问题,在多线程环境下可以预先加载类的静态实例,当虚拟机加载完成类后就会创建类的静态变量,甭管你到时用不用,反正给你留在那里。所有线程访问到的都是同一静态实例,有人也称这种方式为饿汉式,具体写法如下:
上面写法实现单例也是没有问题的,但是有些同学就会觉得如果我只是想调用一个类的某个静态方法,并不想生成它的实例,那有没有其他方法呢,经过各路大神的指点结合自身的总结,可以使用内部静态类来实现这个需求。
开发的同学都知道,虚拟机在加载类的过程中一开始并不会初始化类的内部静态类。如果线程调用内部静态类时,虚拟机只会初始化一次,这样既可以实现单例,同时也是线程安全的。具体写法如下:
除了以上讲到的几种方式外,JDK自身的枚举类型本身就是单例的实现,调用者不能显式的调用构造器完成实例创建,因此很多Java规范文档推荐使用枚举来实现单例。
当然对于初级开发人员而言,现在的主流开发框架都提供单例/多例模式供开发者选择,这样的好处让开发者更多关注业务功能开发,而不用过多关注虚拟机内部类实例创建问题。例如spring中默认类注入就是单例的,可以根据实际情况设置scope为singleton(单例)或者prototype(多例),如下图所示:
到此,关于“java单例模式实例分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
文章标题:java单例模式实例分析
本文路径:http://cdiso.cn/article/ipoojg.html