单例模式
单例模式指的是在软件系统中,对于某个类而言,只能存在一个对象实例
单例模式的特征
- 类的构造器私有化
- 在类的内部创建类的对象
- 提供公有的静态方法,返回类的对象
- 要求对象也声明为静态的
单例模式的分类
饿汉式
饿汉式指的是在该单例类被加载时,即创建该类的对象。
懒汉式
懒汉式类似于懒加载,当需要获取该类的对象时,才创建该类的对象。
单例模式的实现
饿汉式
饿汉式的单例模式实现,并没有线程安全的问题,因为它在类被加载的时候,就被直接创建了,而再次被调用时,返回的都是同一个对象
class Singleton{
private Singleton(){}
private static Singleton instance = new Singleton();
private static Singleton getInstance(){
return instance;
}
}
懒汉式
跳过懒汉式的线程不安全版本,直接冲最终版本:
- 最内层
if
作用:基本作用,当首次访问时,需要创建一个对象再返回(总不能返回空的吧) synchronized
作用:若没有该关键字时,会有线程不安全问题,如果很巧,有多个线程同时执行了getInstance
方法,同时进入了内层if
中时,就会同时分别new出自己的对象!就不符合单例模式的定义:只能有一个对象,则单例就被破坏了,所以需要加锁限定只能有一个线程能够进入- 最外层
if
作用:synchronized
解决了线程不安全问题,那现在有一个线程进入了最内层if
,调用了该类的构造器,若没有最外层if
,当构造完成后,以后又有一堆线程“冲到”锁的门口,等待一个一个拿锁关锁…就很影响销量,所以在锁外面再加上一个if
判断,所有的线程便可以异步地判断是否为空,快速(愉快)的返回单例的对象啦! - 对象为
static
的原因:申明该对象为类对象,保证全局唯一 - 对象为
volatile
的原因:为了保证在new操作中,不会进行指令重排序,从而更保证程序的安全
public class Singleton {
private static volatile Singleton instance;
private Singleton(){}
private static Singleton getInstance(){
if(instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}