单例模式
定义
保证一个类在运行期间仅有一个实例,并提供一个访问它的全局访问点
结构与说明
饿汉式
懒汉式
Singleton:负责创建Singleton类自己的唯一实例,并提供一个getInstance的方法,让外部来访问这个类的唯一实例。
代码
/**
* 饿汉式
*/
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getSingleton(){
return singleton;
}
}
/**
* 懒汉式
*/
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
范围
一个ClassLoader及其子ClassLoader的范围
命名
方法一般命名为getInstance
体现思想
延迟加载(Lazy Load)
一开始不要加载资源或者数据,一直等到马上就要使用这个资源或数据,节约资源。
缓存
如果某些资源或者数据会被频繁的使用,可以把这些数据缓存到内存里面,每次操作的时候查看内存中是否有,有就获取,没有就存入。缓存可以节省大量事件,典型的空间换时间的方案。
缓存中获取数据步骤
- 先从缓存中取值
- 判断缓存中是否有值
- 如果有值可以直接使用这个值
- 如果没有值,获取需要的数据,并把它存入缓存中
理解单例模式
优缺点
1、时间和空间:懒汉式是经典的时间换空间、饿汉式是典型的空间换时间
2、线程安全:(1)不加同步的懒汉式是线程不安全的。
(2)饿汉式是线程安全的、虚拟机保证只会装载一次。
3、实现懒汉式线程安全
(1)加synchronized保证线程安全
/**
* 线程安全懒汉式
*/
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public static synchronized Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
(2)双重检查加锁
/**
* 双重校验锁
*/
public class Singleton2 {
private static Singleton2 singleton = null;
private Singleton2(){
}
public Singleton2 getSingleton() {
if (singleton == null) {
synchronized (Singleton2.class) {
if (singleton == null) {
singleton = new Singleton2();
}
}
}
return singleton;
}
}
并不是每次进入getInstance都不需要同步,而是先不同步,进入方法过后先检查
实例是否存在,如果不存在进入下面同步块,这是第一重检查。进入同步块过后,再次
检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。
这样就只需同步一次,从而减少了多次在同步情况下进行判断所浪费的时间。
双重检查加锁机制的实现会使用一个关键字volatile,被该变量修饰的变量值,不会被本地线程缓存,所有
读写操作共享内存,确保多个线程能正确的处理。
注:java5及以上
更好的单例实现方式
Lazy initialization holder class 模式,这个综合使用了Java的类级内部类和多线程缺省同步锁的知识,很巧妙的同时实现了延迟加载和线程安全。
/**
* Lazy initialization holder class模式
*/
public class Singleton3 {
private static class SingletonHolder{
//JVM保存线程安全
private static Singleton3 singleton = new Singleton3();
}
private Singleton3(){
}
public static Singleton3 getSingleton(){
return SingletonHolder.singleton;
}
}
单例与枚举
语法级控制,JVM保证单例
/**
* 单例和枚举
*/
public enum Singleton4 {
//枚举的一个实例 == public final static Singleton4 enumSingletonInstance = new enumSingletonInstance();
enumSingletonInstance;
//功能处理方法
public void SingleOperate(){
System.out.println("Singleton..."+Singleton4.enumSingletonInstance.hashCode());
}
}
本质
控制实例数目