单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式有饿汉式和懒汉式两种实现方法。
饿汉式:顾名思义饿了比较着急,在类装载时就创建对象实例,所以要提前占用系统资源,长时间占用空间,获取对象实例较快,属于以空间换时间。
懒汉式:顾名思义比较懒需要时才创建,单例访问方法第一次被调用时才实例化对象,获取对象时需要判断对象是否已存在,相对需要更多的时间,属于以时间换空间。懒汉式会面临多线程访问的安全性问题,需要做双重锁定处理才可以保证安全。
饿汉式的单例模式:
懒汉式的单例模式:
总结:饿汉式是在jvm启动加载单例类时就实例化对象,只实例化一次,以后用到的时候就不需要再去实例化了,加载类的时候速度比较慢,但以后获得对象时的速度比较快,该对象从加载到应用结束一直占用资源。
懒汉式相当于一个延迟加载机制,即你需要这个对象时候才去实例化,加载类的时候速度比较快,但以后获得对象时的速度比较慢,该对象在整个应用的生命周期只有一部分时间占用资源。
所以,到底使用哪一种方式,要看实际的需求。
============================================================================
附:java中一种更高效的实现方式(既实现了延迟加载又实现了线程安全):
package com.gyb;
public class Singleton {
/*
* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系,而且只有
* 被用到时才会被装载,这样就相当于实现了延迟加载。
*/
private static class SingletonLoader {
//静态初始化器,由jvm保证线程安全
private static Singleton instance = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingletonLoader.instance;
}
}
当getInstance()第一次被调用时,第一次读取SingletonLoader.instance,导致SingletonLoader被装载并初始化,静态域初始化从而创建实例。由于是静态域,因此只会在虚拟机装载类时初始化一次,并由虚拟机来保证线程安全性。