单例模式
定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
封装唯一实例,可以严格控制客户怎样访问它以及何时访问它,它是唯一实例的受控访问。
UML图
用例
工具箱只能有一个实例。
public class Singleton{
//创建一个Singleton的对象
private static Singleton2 instance;
//私有化构造函数,使得外界不可能利用new创造该类
private Singleton2(){
//获取唯一一个可用的对象
public static Singleton getInstance(){
if(instance == null)
//若实例不存在,则new一个新实例,否则返回已有的实例
instance = new Singleton();
return instance;
}
}
多线程时的单例
public class Singleton {
// ThreadLocal 线程局部变量,将单例instance线程私有化
private static ThreadLocal<Singleton> threadlocal = new ThreadLocal<Singleton>();
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
synchronized (Singleton.class) {
if (instance == null) // 第二次检查:该单例是否被创建
instance = new Singleton();
}
threadlocal.set(instance); // 将单例放入ThreadLocal中
return threadlocal.get();
}
}
双重锁定
public class Singleton {
// ThreadLocal 线程局部变量,将单例instance线程私有化
private static ThreadLocal<Singleton> threadlocal = new ThreadLocal<Singleton>();
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
// 第一次检查:若线程第一次访问,则进入if语句块;否则,若线程已经访问过,则直接返回ThreadLocal中的值
if (threadlocal.get() == null) {
synchronized (Singleton.class) {
if (instance == null) // 第二次检查:该单例是否被创建
instance = new Singleton();
}
threadlocal.set(instance); // 将单例放入ThreadLocal中
}
return threadlocal.get();
}
}
饿汉式单例类:自己被加载时就将自己实例化。而不是之前在第一次被引用时,才会将自己实例化。
// 饿汉式单例
public class Singleton1{
// 指向自己实例的私有静态引用,主动创建
private static Singleton1 singleton1 = new Singleton1();
// 私有的构造方法
private Singleton1(){}
// 以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton1 getSingleton1(){
return singleton1;
}
}