一、单例模式简单理解
单例模式:即某个类在程序运行过程中只被实例化一次,也就是说该类在程序的生存周期里只有一个实例对象。
使用单例模式好处:由于这个类只实例化一次,不管多少个类中用到了这个类,也都只有一个该类的对象。因此,
减少了类实例对象的创建-->减小了GC压力-->提升了程序的性能。
二、单例模式的几种常见写法
/**
* 饿汉式(线程安全)。类加载时就创建唯一的单例实例,不管后面用不用都创建了再说
* 空间换时间的思想,
*/
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
/**
* 饿汉变种模式,使用静态代码块。包括上面的那种饿汉式写法也都是线程安全的
* 因为这两种方法实际上间接地使用了synchronized关键字,具体怎么用到的呢?
* 这就要去了解类加载的机制和过程了
*/
public class Singleton{
private static Singleton instance = null;
static{
instance = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return this.instance;
}
}
/**
* 懒汉式(非线程安全,可以在创建函数前加synchronized关键字变为线程安全)
* 单例实例在使用时才创建
*/
public class Singleton{
private static Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){ //方法前加synchronized关键字变为线程安全,但是会增加创建的时间消耗
if (instance==null){
instance = new Singleton();
}
return instance;
}
}
/**
* 懒汉方式(线程安全双重检查锁版本)
*/
public class Singleton{
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton() {
if (singleton==null){ //第一重检查
synchronized (Singleton.class){
if (singleton==null){ //第二重检查
singleton = new Singleton();
}
}
}
return singleton;
}
/**
* 枚举实现线程安全的单例模式
* 其底层是依赖Enum类实现的,而枚举类的成员变量其实都是静态类型的,并且是在
* 静态代码块中实例化的,有点像饿汉模式,也是天然线程安全的
*/
public Enum Singleton{
INSTANCE;
public void getInstance{
}
}
/**
* 使用ThreadLocal实现线程安全的单例
* 也是空间换时间的方式(因为ThreadLocal会为每一个线程提供一个独立的副本)
* 它是多个线程对数据的访问相互独立
*/
public class Singleton{
private static f