1、什么是单例模式?
一、定义
Singleton模式要求一个类有且仅有一个实例,而且提供了一个全局的访问点。这就提出了一个问题:如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?客户程序在调用某一个类时,它是不会考虑这个类是否只能有一个实例等问题的,因此,这应该是类设计者的责任,而不是类使用者的责任。java
<!--more-->数据库
从另外一个角度来讲,Singleton模式其实也是一种职责型模式。由于咱们建立了一个对象,这个对象扮演了独一无二的角色,在这个单独的对象实例中,它集中了它所属类的全部权力,同时它也肩负了行使这种权力的职责安全
二、单例模式的优势
1)在单例模式中,活动的单例只有一个实例,对单例类的全部实例化获得的都是相同的一个实例。这样就 防止其它对象对本身的实例化,确保全部的对象都访问一个实例工具
2)单例模式具备必定的伸缩性,类本身来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。性能
3)提供了对惟一实例的受控访问。spa
4)因为在系统内存中只存在一个对象,所以能够 节约系统资源,当 须要频繁建立和销毁的对象时单例模式 无疑能够提升系统的性能。线程
5)容许可变数目的实例。设计
6)避免对共享资源的多重占用。日志
三、单例模式的应用场景
单例模式只容许建立一个对象,所以节省内存,加快对象访问速度,所以对象须要被公用的场合适合使用,如多个模块使用同一个数据源链接对象等等。如:code
1)须要频繁实例化而后销毁的对象。
2)建立对象时耗时过多或者耗资源过多,但又常常用到的对象。
3)有状态的工具类对象。
4)频繁访问数据库或文件的对象。
如下都是单例模式的经典使用场景:
1)资源共享的状况下,避免因为资源操做时致使的性能或损耗等。如上述中的日志文件,应用配置。
2)控制资源的状况下,方便资源之间的互相通讯。如线程池等
2、单例的四种实现方式
一、饿汉式
饿汉式: 在类装载的时候就急速的初始化,饿汉式是线程安全的、 可是没有延迟加载
/** * 饿汉式 */ class Singleton_one { // 一、私有化构造器 private Singleton_one() { } // 二、初始化 private static Singleton_one instance = new Singleton_one(); public static Singleton_one getInstance() { return instance; } }
二、懒汉式(同步方法)
单纯的懒汉式是存在线程安全问题的、须要咱们使用同步策略
/** * 懒汉式(同步方法) */ class Singleton_two { // 一、私有化构造器 private Singleton_two() { } private static Singleton_two instance = null; public synchronized static Singleton_two getInstance() { if (instance == null) { instance = new Singleton_two(); } return instance; } }
三、懒汉式(Dubbo Check)
单纯的懒汉式是存在线程安全问题的、须要咱们使用同步策略、这里使用了双重校验
/** * 懒汉式(Double Check) */ class Singleton_three { // 私有化构造器 private Singleton_three() { } private static Singleton_three instance = null; public static Singleton_three getInstance() { if (instance == null) { synchronized (Singleton_three.class) { if (instance == null) { instance = new Singleton_three(); } } } return instance; } }
四、静态内部类
1)静态内部类的加载时机
- 外部类初次加载,会初始化静态变量、静态代码块、静态方法,但不会加载内部类和静态内部类。
- 实例化外部类,调用外部类的静态方法、静态变量,则外部类必须先进行加载,但只加载一次。
- 直接调用静态内部类时,外部类不会加载。
/** * 内部类实现单例模式 * <p> * 既不用加锁 、也能实现懒加载 * * * 外部类初次加载的时候不会加载内部类和静态内部类 */ class Singleton_four { private static int a = 10; // 私有化构造器 private Singleton_four() { } private static class Inner { static Singleton_four instance = new Singleton_four(); } public static Singleton_four getInstance() { return Inner.instance; } }