设计模式——单例模式

简单来说,单例模式,就是为了保证一个类仅仅只有一个实例,并且提供一个访问它的全局访问。

 特点:

1.单例确保自己只有个实例(构造器私有:不被外部实例化,也不被集成)

2.单例必须自己创建自己的实例

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

应用:

资源管理器,回收站,打印机资源,线程池,缓存,配置信息类,管理类,控制类,门面类,代理类通常被设计为单例类

如果应用多个类加载器又同时使用单例模式就会出现多个单例并存。

 

  示例中一个饿汉模式单例,一个懒汉模式。

  饿汉模式:

  在单例类被加载时候,就实例化一个对象交给自己引用。

复制代码
1 public class Singleton1 {
2     //饿汉式
3     private static Singleton1 singleton = new Singleton1();
4     private Singleton1(){}
5     public static Singleton1 getSingleton(){
6         return singleton;
7     }
8 
9 }
复制代码

 懒汉模式,是指需要用的时候才去加载,如果开销比较大,希望用到时候才被加载,就用懒汉模式

复制代码
 1 public class Singleton2 {
 2     //懒汉式
 3     private static Singleton2 singleton;
 4     private Singleton2() {
 5     }
 6     public static synchronized Singleton2 getInstance() {
 7         if (singleton == null) {
 8             singleton = new Singleton2();
 9         }
10         return singleton;
11     }
12 }
复制代码

同步一个方法的时候会造成执行效率下降,所以如果getInstance方法频繁使用就要重新考虑优化了

这里有个错误的实例

复制代码
 1 public class ErrorSingleton {
 2     //单例模式错误示例
 3     private ErrorSingleton errorSingleton = null;
 4     private ErrorSingleton(){}
 5 
 6     public ErrorSingleton getInstance(){
 7         if (this.errorSingleton == null){
 8             this.errorSingleton = new ErrorSingleton();
 9         }
10         return this.errorSingleton;
11     }
12 }
复制代码

我们看下错误实例中getInstance()判断null的部分,假如有线程A执行到这里申请分配内存,可能需要0.001微秒,在这0.001微秒内,线程B执行到判断isNull这个方法,这里到底会判断是否为空呢?

肯定是为空,于是线程B也往下走,这么就出现了两个ErrorSingleton实例了。此时就出问题了。这里要注意。

 

单例模式中还需要注意的问题,不要通过反射去获取单例对象,否则会实例化一个新对象。

测试例子

复制代码
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> classType = Singleton3.class;
        Constructor<?> c = classType.getDeclaredConstructor(null);
        c.setAccessible(true);

        Singleton3 s1 = (Singleton3) c.newInstance();
        Singleton3 s2 = Singleton3.getInstance();

        System.out.println(s1 == s2);
    }
复制代码

输出为false。

暂时就这么多。

posted @ 2017-05-02 17:13  splide  阅读(305)  评论(0)    收藏  举报