Java单例模式的深入了解_第1页
Java单例模式的深入了解_第2页
Java单例模式的深入了解_第3页
Java单例模式的深入了解_第4页
Java单例模式的深入了解_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第Java单例模式的深入了解实际上,这些原则的目的只有一个:降低对象之间的耦合,增加程序的可复用性、可扩展性和可维护性。

记忆口诀:访问加限制,函数要节俭,依赖不允许,动态加接口,父类要抽象,扩展不更改。

在程序设计时,我们应该将程序功能最小化,每个类只干一件事。若有类似功能基础之上添加新功能,则要合理使用继承。对于多方法的调用,要会运用接口,同时合理设置接口功能与数量。最后类与类之间做到低耦合高内聚。

二、单利模式

1.1、单例模式的相关定义

指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。

单利模式三个特点

单例类只有一个实例对象;

该单例对象必须由单例类自行创建;

单例类对外提供一个访问该单例的全局访问点。

单例模式的优点

单例模式可以保证内存里只有一个实例,减少了内存的开销。

可以避免对资源的多重占用。

单例模式设置全局访问点,可以优化和共享资源的访问。

单例模式的缺点:

单例模式一般没有接口,扩展困难。如果要扩展,则除了修改原来的代码,没有第二种途径,违背开闭原则。

在并发测试中,单例模式不利于代码调试。在调试过程中,如果单例中的代码没有执行完,也不能模拟生成一个新的对象。

单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则。

单例模式的应用场景

需要频繁创建的一些类,使用单例可以降低系统的内存压力,减少GC。

某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。

某些类创建实例时占用资源较多,或实例化耗时较长,且经常使用。

某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。

频繁访问数据库或文件的对象。

对于一些控制硬件级别的操作,或者从系统上来讲应当是单一控制逻辑的操作,如果有多个实例,则系统会完全乱套。

当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如Web中的配置对象、数据库的连接池等。

1.2、单利模式的结构

单例类:包含一个实例且能自行创建这个实例的类。

访问类:使用单例的类。

2.1单利模式的实现方式一:懒汉式

该模式的特点是类加载时没有生成单例,只有当第一次调用getlnstance方法时才去创建这个单例。

代码:

publicclassLazySingleton{

//构造器私有,堵死了外界利用new创建此类对象的可能

privateLazySingleton(){

System.out.println(yese

//提供对象,是外界获取本类对象的唯一全局访问点

privatestaticLazySingletonlazySingleton;

publicstaticLazySingletongetInstance(){

//如果对象不存在,就new一个新的对象,否则返回已有的对象

if(lazySingleton==null){

lazySingleton=newLazySingleton();

returnlazySingleton;

}

@Test

publicvoidtestLazy(){

LazySingletonl1=LazySingleton.getInstance();

LazySingletonl2=LazySingleton.getInstance();

System.out.println(l1+\n+l2);

System.out.println(l1==l2);

}

测试结果:

com.singletonPattern.LazySingleton@78e03bb5

com.singletonPattern.LazySingleton@78e03bb5

true

该代码很显然是不适合多线程模式的,这时候就需要给单例模式的对象加上一把锁

classLazySingleton2{

//构造器私有,堵死了外界利用new创建此类对象的可能

privateLazySingleton2(){

System.out.println(s2

//提供对象,是外界获取本类对象的唯一全局访问点

privatestaticLazySingleton2lazySingleton2;

publicstaticLazySingleton2getInstance(){

//如果对象不存在,就new一个新的对象,否则返回已有的对象

if(lazySingleton2==null){

synchronized(LazySingleton2.class){

if(lazySingleton2==null){

lazySingleton2=newLazySingleton2();

returnlazySingleton2;

}

这时还有一个问题,就是在创建一个对象时,在JVM中会经过三步:

(1)为对象分配内存空间

(2)初始化该对象

(3)将该对象指向分配好的内存空间

那么在执行我们这个多线程代码的过程中,有可能他不按照这三部的顺序走,那么就会导致一个指令重排的问题,解决此问题的方法就是加关键字volatile

classLazySingleton3{

//构造器私有,堵死了外界利用new创建此类对象的可能

privateLazySingleton3(){

//提供对象,是外界获取本类对象的唯一全局访问点

privatevolatilestaticLazySingleton3lazySingleton3;

publicstaticLazySingleton3getInstance(){

//如果对象不存在,就new一个新的对象,否则返回已有的对象

if(lazySingleton3==null){

synchronized(LazySingleton3.class){

if(lazySingleton3==null){

lazySingleton3=newLazySingleton3();

returnlazySingleton3;

}

最后我们还可以去解决一下反射来破坏单利模式

classLazySingleton4{

//提供变量,控制反射

publicstaticbooleans=false;

//构造器私有,堵死了外界利用new创建此类对象的可能

privateLazySingleton4(){

if(s==false){

//当第一个对象成功获取之后,第二个对象就不能通过反射获取了

s=true;

}else{

thrownewRuntimeException(不要用反射破坏异常

//提供对象,是外界获取本类对象的唯一全局访问点

privatevolatilestaticLazySingleton4lazySingleton4;

publicstaticLazySingleton4getInstance(){

//如果对象不存在,就new一个新的对象,否则返回已有的对象

if(lazySingleton4==null){

synchronized(LazySingleton4.class){

if(lazySingleton4==null){

lazySingleton4=newLazySingleton4();

returnlazySingleton4;

}

volatile,synchronized这两个关键字就能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。

2.2单利模式的实现方式一:饿汉式

该模式的特点是类一旦加载就创建一个单例,保证在调用getInstance方法之前单例已经存在了。

代码:

publicclassHungrySingleton{

privatestaticfinalHungrySingletoninstance=newHungrySingleton();

privateHung

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论