[设计模式]-单例模式

来源:互联网 发布:simsun.ttc linux 编辑:程序博客网 时间:2024/05/17 03:53
定义确保一个类只有一个实例,并提供一个全局访问点

类图

单例模式的三要素

  • 私有的构造方法
  • 指向自己实例的私有静态引用
  • 以自己实例为返回值的静态的公有的方法

懒汉式实现1:

/** *@author April *@Date: 2013-12-24 */public class SingletonA {//私有构造方法private SingletonA(){}//指向自己的私有静态引用private static SingletonA instance = null;//返回自己实例的公有静态方法public static SingletonA getInstance() {if (instance == null) {instance = new SingletonA();}return instance;}}
懒汉式实现2:
/** * 懒汉式-延迟加载: * 比起SingletonA在方法中多了一个synchronized修饰符,可以保证线程安全。 * 但是有个很大(至少耗时比例上很大,绝大部分的耗时都用在synchronized的同步上)的性能问题, * 多线程的时候每次都会在1这里产生阻塞 */public class SingletonB {private SingletonB(){}private static SingletonB instance = null;public synchronized static SingletonB getInstance() {//1--if (instance == null) {instance = new SingletonB();}return instance;}}
饿汉式实现:
/** * 恶汉式-急切加载:依赖JVM在加载该类时马上创建该类的实例。JVM保证任何线程访问instance静态变量前,一定先创建此实例 */public class SingletonC {private SingletonC(){}//在静态初始化器创建单件。保证线程安全private static SingletonC instance = new SingletonC();public static SingletonC getInstance() {return instance;}}
双重锁定检查:
/** * 双重锁定检查:确保线程安全,又保证性能不受很大影响 *  */public class SingletonD {private SingletonD(){}/** * volatile关键词:被其修饰的变量的值,将不会被本地线程缓存, *所有对该变量的读写都直接操作共享内存,从而保障多线程能正确处理该变量 * volatile只适用于java1.5及以上 */private volatile static SingletonD instance = null;public static SingletonD getInstance() {if(instance==null){synchronized(SingletonD.class){if (instance == null) {instance = new SingletonD();}}}return instance;}}
更好的单例实现
Lazy initialization holder class 模式
  • 类级内部类:有static修饰的成员式内部类。
    • 相当于其外部类的static成分,它的对象与外部类对象间不存在依赖关系,因此可以直接创建。
    • 类级内部类中,可以定义静态方法
    • 类级内部类相当于其外部类的成员,只有在第一次被使用的时候才会被加载
  • 多线程缺省同步锁:多线程开发中,为解决并发问题,主要通过synchronized来加互斥锁进行同步控制。但某些情况下JVM已经隐含为你执行了同步,就不用自己再同步控制了,这些情况包括:
    • 由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时
    • 访问final字段时
    • 在创建线程之前创建对象时
    • 线程可以看见它将要处理的对象时
/** * 通过JVM保证线程安全,getInstance并没有同步,所以延迟加载没有增加任何访问成本 */public class SingletonE{/** * 类级内部类,也就是静态的成员式内部类,只有在调用到时才加载,从而实现延迟加载 */private static class SingletonHolder{//静态初始化器,由JVM来保证线程安全private static SingletonE instance = new SingletonE();}private SingletonE(){ }public static SingletonE getInstance(){return SingletonHolder.instance;}}

单例和枚举

单元素的枚举类型已经成为实现Singleton的最佳方法——《高效Java 第二版》
  • Java枚举类型实质上是功能齐全的类,因此可以有自己的属性和方法
  • Java枚举类型的基本思想是通过公有的静态final域为每个枚举常量导出实例的类
  • 从某种角度讲,枚举是单例的泛型化,本质上是单元素的枚举
  • /** * 枚举来实现单例模式的示例 */public enum SingletonF{//定义一个枚举元素,它就代表了Singleton的一个实例uniqueInstance;//示意方法,单例可以有自己的操作public void singletonOperation(){ }}

单例模式的优点:

  • 在内存中只有一个对象,节省内存空间。
  • 避免频繁的创建销毁对象,可以提高性能。
  • 避免对共享资源的多重占用。
  • 可以全局访问。


0 0
原创粉丝点击