---

2015/10/25

layout: post
title: "设计模式——单例模式"
category: Reading Notes

tags: ["读文章", “设计模式”]

{% include JB/setup %}

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式中的‘单例’通常用来代表那些本质上具有唯一性的系统组件(或者叫做资源)。比如文件系统、资源管理器等。

实现一:

public class Singleton {

    //在自己内部定义自己一个实例
    //注意这是private 只供内部调用
    private static Singleton instance = new Singleton();

    //如上面所述,将构造函数设置为私有
    private Singleton(){
    } 

    //静态工厂方法,提供了一个供外部访问得到对象的静态方法  
  public static Singleton getInstance() {
    return instance;   
  } 
}

下面这种方式被称为懒汉式

实现二:

public class Singleton {

    //和上面有什么不同?
    private static Singleton instance = null;

    //设置为私有的构造函数
    private Singleton(){
    } 

    //静态工厂方法
    public static synchronized Singleton getInstance() {
        //这个方法比上面有所改进
         if (instance==null)
              instance=new Singleton();
         return instance;   
    }
}
  1. 他们的构造函数都是私有的,彻底断开了使用构造函数来得到类的实例的通道,但是这样也使得类失去了多态性
  2. 在第二种方式中,对静态工厂方法进行了同步处理,为了防止多线程环境中产生多个实例;而在第一种方式中则不会存在这样的问题
  3. 在第二种方式中,将类对自己的实例化延迟到第一次被引用的时候。而在第一种方式中则是在类被加载的时候

这样一来每次调用getInstance()方法是都会被加锁,而我们只需要在第一次调用getInstance()的时候加锁就可以了。这显然影响了我们程序的性能。

//内部类实现懒汉式  
public class Singleton {  
    private static class SingletonHolder{  
        //单例变量    
        private static Singleton instance = new Singleton();  
    }  

    //私有化的构造方法,保证外部的类不能通过构造器来实例化。  
    private Singleton() {  

    }  

    //获取单例对象实例  
    public static Singleton getInstance() {  
        System.out.println("我是内部类单例!");  
        return SingletonHolder.instance;  
    }  
}  
因为java机制规定,内部类SingletonHolder只有在getInstance()方法第一次调用的时候才会被加载(实现了lazy),而且其加载过程是线程安全的(实现线程安全)。内部类加载的时候实例化一次instance