单例模式(Singleton Pattern):确保某一个类只有一个实例,并且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象建立型模式。git
单例模式有三个要点:一是某个类只能有一个实例;二是它必须自行建立这个实例;三是它必须自行向整个系统提供这个实例。单例模式是结构最简单的设计模式一,在它的核心结构中只包含一个被称为单例类的特殊类。单例模式结构如图所示:设计模式
public class Singleton { private static Singleton singleton; private Singleton() { } public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
public class EagerSingleton { private static EagerSingleton eagerSingleton = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return eagerSingleton; } }
public class LazySingleton { private static LazySingleton instance = null; private LazySingleton() { } //锁的范围过大,性能下降 synchronized public static LazySingleton getInstance() { if (null == instance) { instance = new LazySingleton(); } return instance; } }
上面的懒汉单例使用synchronzed
进行线程锁,范围过大,影响性能,可使用双重检查锁定(Double-CheckLocking)来实现懒汉式单例类,代码以下:安全
class LazySingleton2 { //volatile保证多线程间共享变量的可见性 private volatile static LazySingleton2 instance = null; private LazySingleton2() { } //双重检查锁定(Double-Check Locking) public static LazySingleton2 getInstance() { //第一重判断 if (null == instance) { //锁定代码块 synchronized (LazySingleton2.class) { //第二重判断 if (null == instance) { instance = new LazySingleton2(); } } } return instance; } }
饿汉式单例类不能实现延迟加载,无论未来用不用始终占据内存;懒汉式单例类线程安全控
制烦琐,并且性能受影响。多线程
还有一种更好的单例实现方式,称之为Initialization Demand Holder (IoDH)的技术,既能够实现延迟加载,又能够保证线程安全,不影响系统性能.在IoDH中,咱们在单例类中增长一个静态(static)内部类,在该内部类中建立单例对象,再将该单例对象经过getInstance()方法返回给外部使用,实现代码以下:函数
class Singleton2 { private Singleton2() { } private static class HolderClass { private final static Singleton2 instance = new Singleton2(); } public static Singleton2 getInstance() { return HolderClass.instance; } }
单例模式可确保只有一个实例对象,其提供了实例的全局访问点来得到该实例,为了不多线程访问的隐患,可以使用饿汉单例模式和IoDH技术的懒汉单例模式。性能