这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
什么是单例模式?
单例模式定义:保证一个类仅有一个实例,并提供访问此实例的全局访问点。
从类别上来看,单例模式属于创建类型的一种常用的[软件设计模式]。通过单例模式的方法创建的类在当前进程中只有一个[实例](根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)可以说是设计模式中最简单的一个了。
单例模式用途
如果一个类负责连接数据库的线程池、日志记录逻辑等等,此时需要单例模式来保证对象不被重复创建,以达到降低开销的目的。
懒汉式单例(线程安全)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式单例(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
/**
在用户第一次调用时初始化,虽然节约了资源,但第一次加载时需要实例化,反映稍慢一些,而且在多线程不能正常工作。
*/
饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){
}
public static Singleton getInstance() {
return instance;
}
}
/*
√这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。 这种方式基于类加载机制避免了多线程的同步问题,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到懒加载的效果。
*/
双重锁
public class Singleton {
private volatile static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance== null) {
synchronized (Singleton.class) {
if (instance== null) {
instance= new Singleton();
}
}
}
return singleton;
}
}
/*
这种写法在getSingleton方法中对singleton进行了两次判空,第一次是为了不必要的同步,第二次是在singleton等于null的情况下才创建实例。在这里用到了volatile关键字,*/
静态内部类(推荐)
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
分析:第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化sInstance ,这样不仅能确保线程安全也能保证Singleton类的唯一性,所以推荐使用静态内部类单例模式。