`
Funine
  • 浏览: 12803 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

java经典单例模式设计以及一些改进

阅读更多

           一个好的代码,绝对不是靠数量堆上去的,而是靠一个好的,清晰的逻辑,来构建的。就像平常的修房子一样,要先设计好,而不是直接就扛着砖直接盖。在java中的常用的设计模式有,单例模式,装饰者模式,观察者模式,外观模式,工厂模式,模板模式等。在接下来的一个星期内,会好好的介绍一下,自己对于这些设计模式的理解。今天我们先从最简单的单例模式开始。

          很多时候,有些类我们只需要一个实例对象,多了会有问题,像是我们聊天室的管理员,我们的硬件设备打印机等等。那么此时单例模式就提供了一个很好的实现。

          以前我们平常写一个类,在外面可以new出多个对象。

          

 public class A {
	
    }
    public void getA(){
    	A a1=  new A();
    	A a2 = new A();
    }

 

       我们有一个A的类,它可以得到a1,a2两个不同的对象他们分别指向不同的地址值。

      

public class A {
private A(){

}
}

    我们可以通过这样将类私有化之后,那么就不能再外面调用对象。为了得到内部的对象和保证是单一的那么此时,经典的单例模式就出现了。在这里我们以一个用户管理中心为例。

public class UserManage {
private static UserManage um = null;//加载静态对象
//私有化构造是外界不能创建
private UserManage(){

}
//内部进行创建,并将方法,设为共有,供外部调用
public static UserManage getInstance(){
//进行判断,为空时便创建对象
if(um==null){
um = new UserManage();
}
return um;
}
}

    通过静态加载,可以控制它的一个的对象的个数;将构造器私有,只有内部才能调用;最后我们使用getInstance方法,在内部并且当这个方法第一次被调用时,new出对象,并且方法为public 课供外部调用。

     上面所说的都是基本的,经典的单例模式,但是这个是有缺陷的。

      在多线程的情况下,可能多个线程在同一个时间片调用了,getInstance方法,在第一个线程进去的时候,可能第二个也进去了,这时候,第一的对象没有new出来,这时判断也就失效了第二个也new出了对象。这就出现了bug,基于这种比较极端的情况下出现的bug,下面是一些改进的方法。

     方法一:使用同步锁synchronized

   public static synchronized UserManage getInstance(){
    	 if(um==null){
    		 um = new UserManage();
    	 }
    	 return um;
     }

    加上同步锁之后,只能一个线程调用这个方法,前面的以外也就不会出现了。但是,大家都知道,线程锁是非常消耗资源的,如果我们在外面经常调用,就会大大降低程序的性能,当然如果在外面这个方法,调用的比较少就没太大问题呢。

     方法二:“急切”创建法

     

写道
private static UerManage um = new UerManage();

private UserManage(){

}

public static UserManage getInstance(){
return um;
}

    就是在加载类的时候,直接把对象创建出来,就是说类一被加载完成,那么这个对象也就存在了,但是这样就会浪费一些内存资源,可能你在很长时间内都用不到这个方法,或是这个类本身就比较大时是对于资源的浪费。

    方法三:双重检查加锁法

private static UserManage um = null;

private UserManage(){

}

public static UserManage getInstance(){
if(um==null){
synchronized (UserManage.class){
if(um==null){
um = new UserManage();
}
}
}

return um;
}

      此方法也是通过也是通过线程锁来解决,但是这里将线程锁加在第二个判断语句处,当遇到,两个或是多个同时进来的时候,会同时经过那个线程锁,但是只有第一个调用的线程会启动线程锁,在一个整个工程都不会再次用到线程锁,只会在第一次加载的时候使用。这样也很好的保证了,线程的原子性。但是,这样在第一次调用的时候都会加载线程锁,若是这个方法,自始至终都只用到一次,那么也是算浪费了资源。

 

      其实上面介绍了几种对于单例模式的改进,每种都有各自的适用场景。在调用多的时候可以考虑第二,三种,调用次数少时可以考虑第三种,第一种。当然若不是多线程也可以考虑经典模式。不同的场景,应用不同的方法。

    

    

          

分享到:
评论

相关推荐

    java 单例设计模式

    详细介绍了java中单例设计模式各种方式,已经改进方案

    设计模式课程设计---使用6个不同的设计模式完成绘图系统(java)

    运用到的设计模式有备忘录模式,迭代器模式,简单工厂模式,状态模式,模版方法模式,单例模式。 资源包含项目文件(eclipse)以及系统说明(docx文件),系统说明中说明了为什么要使用该模式,使用该模式有什么好处...

    用观察者模式和非观察者模式设计一个交通信号灯调度系统

    用观察者模式设计一个交通信号灯调度系统,...最近看了一些Java中的设计模式,比如最简单的单例模式,抽象工厂模式,观察者模式等。在学习了这些设计模式之后,我又对之前写过的一些程序做了改进,本文贴一个交通信号灯的系统

    实战Java高并发程序设计(第2版)PPT模板.pptx

    5并行模式与算法 5.1探讨单例模式 5.3生产者-消费者模式 5.5future模式 5.2不变模式 5.4高性能的生产者-消费者模式:无锁的实现 5.6并行流水线 01 02 03 04 05 06 实战Java高并发程序设计(第2版)PPT模板全文共25...

    JAVA单例模式源码-JyNI:使Jython能够加载本机CPython扩展

    JAVA例单模式源码JyNI – Jython 本机接口 如果还没有完成,请务必访问我们的项目主页。 目录 1.什么是JyNI? Jython 当前阻碍其更广泛采用的一个问题是它不支持为 CPython 编写的本机扩展,如 NumPy 和 SciPy。 ...

    二十三种设计模式【PDF版】

    设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. ...

    design-patterns:设计模式

    单例模式(单例模式) 结构型模式 适配器模式 改进模式(bridge pattern) 组合模式 装饰器模式 门面模式 享元模式(flyweight pattern) 代理模式(代理模式) 行为模式(行为模式) 责任链模式(责任链模式) 命令...

    design-pattern

    单例模式 抽象工厂模式 建造者模式 原型模式 结构型模式7种 适配器模式 改进模式 装饰模式 组合模式 外观模式 享元模式 代理模式 行为型模式11种 模版方法模式 命令模式 迭代器模式 观察者模式 中介者模式 备注模式 ...

    java 面试题 总结

    JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用...

    超级有影响力霸气的Java面试题大全文档

    超级有影响力的Java面试题大全文档 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。...

    面向对象技术与UML课件及源代码-by 南邮-陈杨

    本书为中南大学精品教材立项项目,分为上下两篇共21章,涵盖了面向对象技术中Java开发环境配置、程序设计基础、面向对象原理以及UML的知识。本书使用的开发环境是JDK 1.6+Eclipse 3.3+Rational Rose 2003,逐步引领...

    pos-system:重新提交代码并改进它

    [题目练习需求]涉及的知识点多态策略模式工厂模式 & 单例模式组合模式装饰者模式商店里进行购物结算时会使用收银机(POS)系统,这台收银机会在结算时根据客户的购物车(Cart)中的商品(Item)和商店正在进行的优惠...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    然而,由于HTML5的W3C标准规范还未制定,安卓系统中类浏览器Webview自身存在一些局限性,因此仍存在着诸多问题亟需解决,包括:(1)多窗口类浏览器模式问题。安卓上用于加载的Webview视图窗口只是作为类浏览器而...

    SomervilleSwag:测试和软件改进小组项目-Derek Somerville Merch Store

    作者 Goudham Suresh,Alan Robinson,Erin Heath,Hazel Fulton,Robert Ranson,Steven Ferguson 目录 项目目的与描述 目的允许客户购买Derek ...引擎使用的设计模式-单例,状态,适配器 展示 JavaX.Swing(JFrames /

    Mybatis-Learning:学习mybatis的demo与总结

    改进成使用util单例模式来获取SqlSession的实例,节省资源,以及从属性文件读取信息,有利于解耦合。 4. 定义别名能让我们快速简洁的看出类型信息,省去许多写路径名的麻烦。 5. 完整的增删改查的demo。 6. 如何在...

    javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象

    当然,如您所知,我们可以改进创建的方式,比如使用全局变量来缓存一个实例(客户端的单例模式?!),对于同步方式的通信,这是很有效的,但是这样的方式对于异步通信会出现问题,因为没有了进程的堵塞,用户可能...

Global site tag (gtag.js) - Google Analytics