确保一个类只有一个实例,而且自行实例化并向系统提供这个实例;提供全局访问的方法java
常见场景:windows的任务管理器(单实例)windows
上面的getInstance方法在多线程状况下,或致使屡次new实例,从而使用方获得的不是同一份实例安全
代码样例:多线程
/** * 饿汉式单例:类加载式就启动实例的初始化,保证使用时实例已建立完毕,从而全部适用方都获取同一份实例 * @author clari * */ public class EagerSingleton { // 类加载时,随即被实例化 private static EagerSingleton instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return instance; } }
代码样例性能
/** * 懒汉式单例 * 第一次使用时才建立,延迟加载,可能资源初始化耗时 * @author clari * */ public class LazySingleton { private volatile static LazySingleton instance = null; private LazySingleton() { } // 双重检查锁定:同时增长volatile确保成员变量能够对多个线程正确处理 private static LazySingleton getInstance() { if (null == instance) { synchronized (LazySingleton.class) { if (null == instance) { instance = new LazySingleton(); } } } return instance; } }
饿汉式:类加载时已实例化,不用考虑多线程访问问题。可是无论实例最终是否会使用,都会提早实例化,可能形成资源的浪费;同时系统加载时需实例化,可能形成系统加载缓慢;spa
懒汉式:第一次使用时实例化,不提早预占资源,必须处理好多个线程访问的问题。实例化时可能会耗费较长时间,意味着多线程同时访问的概率更大,须要双重检查致使系统性能获得损失。线程
IoDH: Initialization on Demand Holder: 类中增长一个静态内部类,内部类建立实例对象。code
第一次调用getInstance()方法时加载内部类,此时初始化该内部类的静态对象instance,由Java虚拟机保证内部类初始化实例的的线程安全性,确保只初始化一次。对象
既实现延迟加载,又保证线程安全,不影响系统性能(getInstance()方法没有任何线程绑定)。blog
public class BetterSingleton { private BetterSingleton() { } private static class HolderClass { private final static BetterSingleton instance = new BetterSingleton(); } private static BetterSingleton getInstance() { return HolderClass.instance; } public static void main(String[] args) { BetterSingleton s1, s2; s1 = BetterSingleton.getInstance(); s2 = BetterSingleton.getInstance(); System.out.println("s1 == s2: " + (s1==s2)); } }
一、没有抽象层,扩展存在困难;
二、职责太重,必定程度违背单一职责原则,同时提供业务方法,也提供建立对象方法,将对象建立和访问耦合一块儿。
三、java实现了垃圾自动回收,若是实例化对象长期不适用,可能会被垃圾回收,后面再适用再次从新实例化,则可能致使共享的单例对象状态的丢失。