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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© tomson_tang 中级黑马   /  2015-2-7 08:57  /  744 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

单例其实就是唯一实例的意思,也就是说一个类只有一个唯一的实例。开发人员都知道,在java里,只要new一个类,就会创建这个类的一个实例,如果把这个类new多次,就会创建这个类的多个实例。有时如果在程序运行时,不管new多少次,只需要创建一个实例,比如日志记录中的管理类,这时就需要用到单例模式。
在数据库连接池上,对于程序而言,若希望池子在系统运行时只有一个,此时,该连接池也需要使用到单例模式来保证这个连接池在系统运行时只有一个实例存在(这里的一个唯一实例当然是相对不同的JDBC驱动而言,可以有一个专属于mysql的连接池,或者一个Oracle的连接池等等,只让一个类型的一个池子在运行)在java中有一个Runtime类,该类是一个与JVM(java虚拟机)运行时环境有关的类,可以用来获取当期的JVM虚拟内存,可以运行JVM的垃圾回收,可以加载动态库等,每个java程序都会有一个Runtime类实例,使应用程序能够与其运行的环境想连接。可以通过getRuntime方法获取当前运行时的Runtime类(应用程序不能创建自己的Runtime类实例),这里的Runtime类就是一个单例模式的典型应用。
创建日志类和建立数据库类实例类似,开发人员不可能没记录一次日志就创建一个日志类的实例,而是要在程序运行时,有一个日志类的唯一实例,每次记录日志时直接调用即可。
总结起来就是,当程序运行时,需要保证一个对象只有一个实例存在时,就应该用到单例模式。

单例模式的实现方法其实很简单,就是定义一个该类的静态变量,然后再定义一个获取该静态变量的静态方法。

示意代码:

通过把该类设置为单例模式,故外界每次获取到的该类的实例均为单一实例。上述单例模式称为饿汉式单例模式。
还有一种称为懒汉式单例模式:

与饿汉式不同的是创建实例的时机不同,饿汉式是在该类被加载时即被调用,而懒汉式则是在需要获取时猜进行创建。
对于单例模式有分为可以于单线程下运行的或者为可以在多线程下运行的,对于懒汉式单例模式,仅能在单线程的程序下运行,若放在了多线程的程序中就会出现问题(如果多个线程同时进行if语句的判断则会创建多个该类的实例,违背了该模式的原则)。故,对于多线程的程序而言,可以为懒汉式单例模式增加同步机制。
增加的方式有2种,称为双检测机制的单例模式:
  • 在getInstance方法处增加同步机制,该方式仅适用于不需要大量地获取该类的实例(由于程序没获取一次该类的实例就得进入同步机制,会导致程序的效率低下)。:
  • 在getInstance方法中的if判断语句中增加同步机制,并且在同步机制内增加多一个if判断:

    这样做的目的是为了避免多次创建该类的实例,如果只是在第一个if判断语句出增加同步机制,将会出现和之前一样的问题,出现多次创建该类的实例的现象,故需要在同步机制中在增加一个if判断,这种方式下,只有第一次创建实例时,才进入同步机制,以后因为实例已经创建,将不会在进入同步机制,因此这种做法,满足了多线程下单例模式的应用,其实,最简单的做法,还是最开始那种,即饿汉式单例模式。





0 个回复

您需要登录后才可以回帖 登录 | 加入黑马