1

編輯:我正在嘗試爲Web應用程序的所有會話創建共享數據庫連接池。另一篇文章說,創建Servlet上下文對象的最佳方式是讓init偵聽器創建它。然而我不清楚如何讓這個對象可供我的servlet使用。您如何創建和以後訪問應用程序級資源?

+1

你能不能給我們一些代碼,這可能有助於解釋你的問題? – Keppil

+1

你不能使用空的構造函數嗎?然後檢查字段以瞭解它是否已被初始化?最後的意義何在? –

+0

請求StackOverflow上的某個人爲您編寫初始化代碼。 –

回答

2

一種解決方案是使用專用支架類:

public class SomeClass { 
    private static class ResourceHolder { 
     private static final Resource INSTANCE = new Resource(); 
    } 

    public static Resource getInstance() { 
     return ResourceHolder.INSTANCE; 
    } 
} 

SomeClass.getInstance()被稱爲第一次實例將被初始化。

+0

這被稱爲[辛格爾頓持有人(http://en.wikipedia.org/wiki/Singleton_pattern#Initialization_On_Demand_Holder_Idiom)圖案。它很乾淨且線程安全,但確實使代碼難以測試和模塊化。因此應謹慎使用。 – dimo414

+0

是否可以延遲初始化這種模式,就像我說我無法訪問在加載時創建此對象所需的參數。 – user3056052

+0

@ user3056052有沒有理由你需要它靜態最終? – assylias

2

你可以做到這一點的另一種方法是使用靜態初始化:

public class SomeClass { 

    private static final Object[] CONTENT; 

    static { 
     CONTENT = new Object[SomeOtherClass.getContentSize()]; // To show you can access runtime variables 
    } 

} 

一旦類是使用類裝入器裝入這將初始化CONTENT陣列。

0

喜歡的東西:

public static abstract class Lazy<T> { 

    private T t = null; 

    public synchronized T get() { 
     if (t == null) { 
      t = create(); 
     } 
     return t; 
    } 

    protected abstract T create(); 
} 

public static final Lazy<List<String>> lazyList = new Lazy<List<String>>(){ 

    @Override 
    protected List<String> create() { 
     return new ArrayList<String>(); 
    } 
}; 
0

我會提醒你前面,你要描述有位代碼的氣味,我懷疑你會做的更好,以完全避免了這種模式。依賴外部運行時狀態的靜態資源打破了有關變量範圍的各種最佳實踐。


你所描述的,但是,將最被無論是SupplierFuture實現什麼,這取決於所涉及的成功構建你所需要的對象的工作。所不同的是有些迂腐,但你通常會使用一個Future舉行,這將需要很長的時間來計算,而Supplier通常很快會返回一個參考。 Future也具有Java的併發實用程序的一些不錯的鉤子,但它的聲音你並不需要。

你會使用一個Supplier像這樣:

public class GlobalState { 
    public static final Supplier<LazyData> MY_DATA = Suppliers.memoize(
    new Supplier<LazyData>() { 
     public LazyData get() { 
     // do whatever you need to construct your object, only gets executed once needed 
     } 
    }); 

    ... 
} 

Suppliers.memoize()將緩存第一次調用底層Supplier的結果在一個線程安全的方式,所以簡單地包裝Supplier給您的通話定義防止重複處理。

1

最簡單的懶初始化是使用enum一個實例。

enum Singleton { 
    INSTANCE; // lazy initialised 
} 

增加的問題是你想要的初始化值。爲了處理這個問題,你可以嵌套這個類。

enum Utility {; 
    static MyType val; 
    static OtherType val2; 

    enum Holder { 
     INSTANCE; 

     Holder() { 
      // uses val and val2 
     } 
    } 

    public static Holder getInstance(MyType val, OtherType val2) { 
     Utility.val = val; 
     Utility.val2 = val2; 
     return Holder.INSTANCE; // only created the first time. 
    } 
} 

注意:這是線程安全的,因爲靜態塊初始化是安全的。

相關問題