A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© onlyonewf 初级黑马   /  2012-6-9 11:24  /  2456 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1) 单态设计模式原理

即是类在内存中只能创建一个实例对象,就是采取一定的方法保证在整个的软件系统中,对某个类只能产生一个对象实例,并且该类只提供一个取得其实例对象的方法.如果我们要让类在一个虚拟机中只能产生一个对象.我们首先必须将类的构造方法的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象.因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法一返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以指向类内部产生的该类对象的变量也必须定义成静态的.

2) 单态设计模式的特点

1、单态类确保自己有却只有一个实例。

2、单态类必须自己创建自己的实例。

3、单态类必须为其他对象提供唯一的实例。

3) 何时用到单态设计模式

第一、控制资源的使用,通过线程同步来控制资源的并发访问;

第二、控制实例产生的数量,达到节约资源的目的。

第三、作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。

比 如,数据库连接池的设计一般采用单例模式,数据库连接是一种数据库资源。软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损 耗,这种效率上的损耗还是非常昂贵的。当然,使用数据库连接池还有很多其它的好处,可以屏蔽不同数据数据库之间的差异,实现系统对数据库的低度耦合,也可 以被多个系统同时使用,具有高可复用性,还能方便对数据库连接的管理等等。数据库连接池属于重量级资源,一个应用中只需要保留一份即可,既节省了资源又方 便管理。所以数据库连接池采用单例模式进行设计会是一个非常好的选择。

在我们日常使用的在Windows中也有不少单例模式设计的组件,象常用的文件管理器。由于Windows操作系统是一个典型的多进程多线程系统,那么在创建或者删除某个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象。采用单例模式设计的文件管理器就可以完美的解决这个问题,所有的文件操作都必须通过唯一的实例进行,这样就不会产生混乱的现象。

再比如,每台计算机可以有若干个打印机,如果每一个进程或者线程都独立地使用打印机资源的话,那么我们打印出来的结果就有可能既包含这个打印任务的一部分,又包含另外一个打印任务的一部分。所以,大多数的操作系统最终为打印任务设计了一个单例模式的假脱机服务Printer Spooler,所有的打印任务都需要通过假脱机服务进行。

实际上,配置信息类、管理类、控制类、门面类、代理类通常被设计为单例类。像Java的Struts、Spring框架,.Net的Spring.Net框架,以及Php的Zend框架都大量使用了单例模式。

4) 单态设计模式的实现

实现1:()

public class Single {  

      private Single()

{

//首先有一个私有的构造函数

        }

private static Single instance; //创建一个自己的对象,

     public static Singleton getInstance() {

     if(instance==null){

         instance=new Singleton ();

      }

      return instance;

     } //提供一个方法给外部使用

}

但是,这种方式是线程不安全的,如果多个线程同时访问的话就可能有多个对象产生,如果在get方法中加同步块的话会影响性能。

实现2:

public class Singleton {

private Singleton(){

}

private static Singleton instance =new Singleton();

public static Singleton getInstance(){

return instance;

}

}

这种方式虽然不存在安全性问题,但是在程序启动的时候就会初始化。

实现3:

public class Singleton {

private static class SingletonHolder {

static Singleton instance = new Singleton();

}

public static Singleton getInstance() {

return SingletonHolder.instance;

}

}

3种方式中这是最好的解决方案,既解决了线程同步的问题,有在调用的时候才初始化

1 个回复

倒序浏览
第三种方式没有私有构造函数啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马