響應式編程羣交流 之 單例模式討論

單例的實現

不追求那麼多花哨的,直接給兩個最實際的用法: 懶漢模式的實現(上海-kotlin-kevin 提供):java

public final class Foo {

    private static class FooLoader {
        private static final Foo INSTANCE = new Foo();
    }

    private Foo() {
        if (FooLoader.INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }
}
複製代碼

點評:react

重慶-java-渣渣:你這用的是靜態內部類,在效率和安全性上都比起其餘的好。web

本人追加:靜態內部類和非靜態內部類同樣,都是在被調用時纔會被加載,以此來實現懶漢模式。所用環境,在單例對象佔用資源大,須要延時加載的狀況下優選。編程

餓漢模式的實現(本人提供):設計模式

//reactor.netty.resources.DefaultLoopNativeDetector
final class DefaultLoopNativeDetector {

	private static final DefaultLoop INSTANCE;

	static {
		if (DefaultLoopKQueue.hasKQueue()) {
			INSTANCE = new DefaultLoopKQueue();
		}
		else if (DefaultLoopEpoll.hasEpoll()) {
			INSTANCE = new DefaultLoopEpoll();
		}
		else {
			INSTANCE = new DefaultLoop() {};
		}
	}

	public static DefaultLoop getInstance() {
		return INSTANCE;
	}
}
複製代碼

杭州_java_小狼: 反射能夠破壞任何形式的單例,想着防止被反射破壞單例,幾乎不大可能,不如想一想怎麼正常使用反射。 反射去獲取單例,不是單例的正常使用方式。按照單例的設計規則,獲取該實例應該由該類自行提供獲取實例的方法,也就是熟悉的getInstance方法。反射去調單例模式,說明這個場景已經不適用單例了。tomcat

本人:爲何用單例,它的場景在哪裏?

杭州_java_小狼:爲何要使用單例?在軟件系統中,常常有這樣一些特殊的類,必須保證它們在系統中只存在一個實例,才能確保它們的邏輯正確性、以及良好的效率(也就是常說的性能優化,代碼優化吧)。 它的場景,我以爲主要是要面對共享資源的訪問與操做,以及控制資源的訪問與操做時,能夠考慮使用單例模式。安全

本人:說白了就是當下容器裏的惟一。這個惟一該如何表達,容器生它生,仍是容器有用到的時候纔有。前者的話就在類加載的時候就給它實例化,也就是說,餓漢式,後者涉及到懶加載也就是懶漢式。性能優化

杭州_java_小狼: 這個應該涉及到了實例化的延遲與否,容器有它有是餓漢式加載,容器用到的時候纔有是懶加載。 本人: 如今內存這麼大,基本餓漢式就能夠了。所謂的設計模式歷來都是從使用場景出發的。oop

小狼:關於你說的單例的相對惟一性

杭州_java_小狼: 好比,在一個應用中咱們使用了Spring,那麼Spring做爲一個容器,裏面的單例是相對Spring容器中的單例;假如這個Sping的應用又部署在Docker容器中,那這個單例的相對惟一性會改變嗎? 也就是,在Docker容器的範圍內,是否容許出現一個單例對象的兩個實例?一個出如今Spring容器中,一個出如今Docker的另一個地方。 好像記得你分享的時候,說過相似的問題,具體是怎麼回事擠不太清楚了。性能

本人:一個tomcat下能夠放置多個web項目,你看彼此是否是獨立的。

杭州_java_小狼: 多謝知秋大哥,你這麼講,我就明白了。

更多精彩請加入QQ羣:響應式編程交流 523409180

相關討論成員博客:

杭州_java_小狼www.jianshu.com/u/0ab97f4c6…

相關文章
相關標籤/搜索