首页 > 代码库 > 单例模式

单例模式

一、什么是单例?

确保一个类只有一个实例,并提供一个全局访问点

二、应用

线程池、缓存、数据库等,只需要一个实例,如果多个实例 会造成异常情况

三、简单实现

1)懒汉式简单实现

①public class Singleton{

  private static Singleton singleton;

  private Singleton(){}

  public static Singleton getInstance(){

    if(singletn==null){//位置一

      singleton = new Singleton();

    }

    return singleton;

  }

}

注:简单的实现对于多线程会有问题,第一次创建singleton时,线程1正在执行位置一,同时线程2又需要一个singleton的实例,她也执行到位置一,致使线程1,2都获取到一个singleton的实例,造成出现两个singleton实例

②解决多线程的问题,加入synchronized同步锁,只准一个进入去创建实例,重新写getInstance方法

public static synchronized Singleton getInstance(){

    if(singletn==null){//位置一

      singleton = new Singleton();

    }

    return singleton;

  }

使用synchronized解决了多线程问题,但是性能降低了,每次进入都要判断一下getInstance这个方法是否已经执行完,但是我们只需要第一次实例化singleton时,判断一下是否执行完这个getInstance方法。

③双重检查加锁,在getInstance减少同步,增加性能:

private volatile static Singleton singleton;//volatile关键字:确保;当singleton被实例化成Singleton时,多个线程正确的处理singleton变量

public static Singleton getInstance(){

  if(singleton == null){//检查实例,如果不存在,进入同步区

    synchronized(Singleton.class){//只有第一次才彻底执行这段代码

      if(singleton == null){//再次判空

        singleton = new Singleton();

      }

    }

  }

}

注:以上是懒汉式的单例模式,也就是延迟加载,用到singleton的时候才创建一个实例。

2)饿汉式单例模式:

①简单实现:

private static Singleton singleton = new Singleton();

public static Singleton getInstance(){

  return singleton;

}

②内部类饿汉式实现方法:

public static Singleton getInstance(){

  return SingletonHolder.instance;

}

private static class SingletonHolder{

  private static Singleton instance = new Singleton();

}

四、总结

1)单例模式确保一个单独实例

2)提供一个全局访问点(getInstance())

3)一个私有构造(Singleton),一个私有静态变量(singleton),一个公有静态方法(getInstance())

单例模式