不追求那麼多花哨的,直接給兩個最實際的用法: 懶漢模式的實現(上海-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…