シングルトンモード
シングルトンモードを実装するには、空腹の人、怠惰な人、列挙型、静的な内部クラスなど、さまざまな方法があります。再
投稿元:https://www.jianshu.com/p/b8c578b07fbc
なぜシングルトンモードを使用するのですか?
シナリオ一部のクラス(主にツールクラス)では、システム全体でタスクを完了するために必要なインスタンスは1つだけです。たとえば、ログ印刷クラス、スレッドプールクラスの取得などです。
利点
- システムにはオブジェクトが1つしかないため、システムリソースが節約され、オブジェクトを頻繁に作成および破棄するオーバーヘッドが削減され、システムパフォーマンスが向上します。
不利益
- インスタンス化されたオブジェクトが長期間使用されない場合、システムによってゴミと見なされてリサイクルされ、オブジェクトの状態が失われます。
実現する方法
- 怠惰な男モード
/**
* <饿汉模式>
* <p>
* 类一旦加载就创建instance实例,getInstance时实例已经存在
*
* @author dkangel
*/
public class SingletonHungry {
private static final SingletonHungry instance = new SingletonHungry();
/**
* 私有构造方法,避免其他类创建实例
*/
private SingletonHungry() {
}
public static SingletonHungry getInstance() {
return instance;
}
}
- 空腹の男モード
/**
* <懒汉模式>
* 只有在getInstance时才去实例化instance
* <p>
* <应用场景>
* 除了初始化单例类时 即 创建单例外,继续延伸出来的是:单例对象 要求初始化速度快 & 占用内存小
*
* @author dkangel
*/
public class SingletonLazy {
/**
* volatile 保证指令重排序的正确性
*/
private volatile static SingletonLazy instance;
/**
* 私有构造方法,避免其他类创建实例
*/
private SingletonLazy() {
}
/**
* <双重校验锁机制>
* <p>
* 第一个if:若实例已经创建,则直接返回,无需加锁
* <p>
* 第二个if:避免多次创建实例
* 如果有两个线程同时调用getInstance()方法,线程A先获取到锁,线程B等待线程A释放锁
* 当线程A执行instance = new SingletonLazy();完毕,释放了锁,此时线程B获取到锁
* 假如没有第二个if判空,则线程B也会执行instance = new SingletonLazy();
* 这样就导致创建了多余的实例
*
* @return SingletonLazy
*/
public static SingletonLazy getInstance() {
if (instance == null) {
synchronized (SingletonLazy.class) {
if (instance == null) {
instance = new SingletonLazy();
}
}
}
return instance;
}
/**
* <同步锁>
* <p>
* 每次访问都要进行线程同步(即 调用synchronized锁)
* 造成过多的同步开销(加锁 = 耗时、耗能)
*
* @return SingletonLazy
*/
public static synchronized SingletonLazy getInstance1() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
}