单例模式

一、前言

设计模式是前人工作的总结和提炼。通常,设计模式都是针对某一特定问题的成熟的解决方案。如果 能合理地使用设计模式,不仅能让系统更容易被他人理解,同时也能使系统拥有更加合理地结构。

单例模式是设计模式中最为普遍的模式之一。它是一种对象创建模式,用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。

  有什么好处?

  1. 对于频繁使用的对象,可以省下创建对象所花费的时间。
  2. new的次数减少,因而对系统内存的使用频率也会降低,减轻GC压力,缩短GC停顿时间

  什么时候用?

对于系统中的关键组件和被频繁使用的对象,使用单例模式可以有效的改善系统性能。

二、一个简单的单例模式

public class Singleton {
    //私有的构造方法
    private Singleton(){
        System.out.println("单例被创建");
    }
    //类加载时创建
    private static Singleton instance =new Singleton();
    //外部程序获取实例的方法
    public static Singleton getInstance(){
        return instance;
    }
    public static void otherMethod() {
        System.out.println("我是Singleton的其他方法");
    }
}

首先单例模式必须要有一个private修饰的构造函数,这样才会确保单例不会被其他代码示例化,其次instance成员变量和getInstance方法必须是static的。

但是这个单例有个缺陷,就是由于instance变量是static的,所以当jvm加载单例类是,单例对象就会被创建,即我们还没有使用单例类,他就被创建出来了,当使用Singleton.otherMethod()时,程序输出

单例被创建
我是Singleton的其他方法

为了解决这个问题,提高系统在调用相关函数的反应数据,就需要引入延时加载机制

public class LazySingleton {
    private LazySingleton(){
        System.out.println("单例被创建了");
        
    }
    private static LazySingleton instance=null;
    public static synchronized LazySingleton getInstance(){
        if(instance==null){
            instance= new LazySingleton();
        }
        return instance;
    }
}

给静态初始化变量instance赋值为null,确保系统启动时没有额外的负载。在getInstance方法中判断instance变量是否存在,如果不存在则创立单例模式。要注意的是,getInstance方法加了synchronized关键字,因为可能出现多线程访问getInstance方法的情况,当线程1在创建单例时,在完成赋值操作前,线程2可能判断instance为null,故也创建一个实例对象。

但是为了使用延时加载引入了同步关键字反而降低了程序的性能,为了解决这个问题,需要对其进行改造

public class StaticSingleton {
    //私有的构造方法
    private StaticSingleton(){
        System.out.println("单例被创建");
    }
    //静态内部类
    private static class SingletonHolder{
        private static StaticSingleton instance=new StaticSingleton();
    } 
    public static StaticSingleton getInstance(){
        return SingletonHolder.instance;
    }
}

使用内部类来维护单例实例,当StaticSingleton类被加载时,其内部类不会被初始化,也就不会初始化instance变量。只有当getInstance方法被条用是,才会加载SingletonHolder,初始化instance。由于实例的创建时在类加载的时候完成的,所以天生对多线程友好也就不用同步关键字。



posted @ 2016-12-20 23:54  一只会编程的猫  阅读(119)  评论(0)    收藏  举报