有你在真好 的个人博客
你真的了解单例模式么?
阅读:2205 添加日期:2021/3/27 23:23:00 原文链接:https://www.toutiao.com/item/6484936024232296974/

应用最广的模式,单列模式应用最广的模式,单列模式

单列模式是用用最广的模式之一。 在应用这个模式的时候,单例对象的类必须在整个应用中只有一个实例存在。单例模式一般有以下几个特点:

1. 构造函数不对外开放,一般都是private。2. 通过一个静态的方法或者枚举返回对象。3. 确保多线程情况下只有一个实例对象。

单例模式通常有如下几种实现情况单例模式通常有如下几种实现情况

饿汉模式

`public class Config {

private static Config CONIG = new Config();

private Config(){}

public static Config getInstance(){ return CONIG; } }` 代码中Config不能通过new的方式来获得,只能通过getInstance的方式来获取。 而这个CONIG对象是静态的对象,并且在声明的时候已经初始化了,这就保证了对象的唯一性。

懒汉模式

懒汉模式是声明一个对象,并且在第一次调用getInstance的时候初始化。

public class Config {

private static Config CONFIG = null;

private Config(){}

public static synchronized Config getInstance(){ if(CONFIG == null){ CONFIG = new Config(); } return CONFIG;}

}

这种模式在getInstance方法前添加了synchronized关键字,保证他是一个同步方法,这就保证了在多线程中这个类的实例的唯一性。 但是你想下,即使Config已经被初始化了,每次调用getInstance都会进行方法同步,这就会消耗不必要的资源,这也是懒汉模式的一大缺点。 总结下,懒汉模式在第一次使用的时候才会实例化资源,最大的缺点是每次调用都需要不必要的同步,也浪费了很多资源。

懒汉模式的改进

public class Config {

private static Config CONFIG = null;

private Config(){}

public static Config getInstance(){ if(CONFIG == null){ synchronized (Config.class) { if(CONFIG == null){ CONFIG = new Config(); } } } return CONFIG;}

}这个改进都在getInstance上,进行了两次判空,一次同步。 第一个判断空是为了不必要的同步,第二次判断空是为了避免在多线程情况下多次创建实例。 因为假如有两个线程同时进入了第此判空,其中一个阻塞到synchronized之外,如果不判断空,第二个线程在执行的时候也会创建一个实例。

静态内部类实现单例模式

public class Config {

private Config(){}

public static Config getInstance(){ return Holder.CONFIG;}

private static class Holder{ private static Config CONFIG = new Config();}

}

这种模式只有当第一次调用getInstance的时候初始化,并且有JVM来保证线程安全与唯一性。 这种方法是推荐使用的单例模式。

枚举单例 这种模式还在研究之中,暂不做评论

ICP备案号:苏ICP备14035786号-1 苏公网安备 32050502001014号