2014-02-10 56 views
1

我有一個監視器類與靜態(和可選final)變量稱爲ClockValues。這個變量被其他靜態方法使用。但是,ClockValues對象來自外部源。有沒有辦法可以確保外部對象和線程在使用此類中的任何靜態方法之前初始化ClockValues? 有點像構造函數,但對於靜態變量。確保靜態變量在使用任何靜態方法之前被初始化?

public class SharedData { 
    private static final MutexSem mutex = new MutexSem(); 
    private static ClockValues clock; 

    //my static "Constructor" 
    //but I can't force other objects to call this method before all other methods in this class 
    //I understand I could use a flag to signal initilization, but I was looking for a cleaner way 
    public static void initialize(ClockValues c){ 
     mutex.take(); 
     clock= c; 
     mutex.give(); 
    } 

    public static void doSomething(){ 
     mutex.take(); 
     //do something with `clock` 
     mutex.give(); 
    } 

//... more methods using `clock` variable 


} 
+3

如果使用初始化程序或靜態塊初始化靜態變量,則應在類加載並初始化時對其進行初始化。你關心什麼特定的代碼? –

+0

(如果沒有,爲什麼它是一個靜態變量/方法?;-) – user2864740

+0

@TedHopp我明白我可以使用靜態塊。但'ClockValues'變量依賴於一個外部類來傳入'ClockValues'的值。所以它必須等待外部電話。 @ user2864740這是一個靜態變量,因爲這是一個多線程程序,我們需要使用靜態監視器來確保併發性。 – Bonk

回答

0

我不認爲你可以做你想要的靜態方法。你也許可以做一些與Singleton模式:

public class SharedData { 
    private static final MutexSem mutex = new MutexSem(); 
    private static SharedData instance; 
    private ClockValues clock; 

    public static SharedData getInstance(ClockValues c) { 
     mutex.take(); 
     if (instance == null) { 
      instance = new SharedData(c); 
     } 
     mutex.give(); 
     return instance; 
    } 

    private SharedData(ClockValues c) { 
     clock = c; 
    } 

    public void doSomething() { // NOTE: no longer static 
     mutex.take(); 
     //do something with `clock` 
     mutex.give(); 
    } 

    //... 
} 

不幸的是,這將需要每次調用getInstanceClockValues值作爲參數傳遞。不過,根據你的架構,這可能是一個可行的選擇。

+0

輝煌,正是我期待的。謝謝! – Bonk

0

標準模式來初始化單身在Effective Java, Second Edition, Item 71描述:

public class AService { 
    private static int init = 0; 
    private static class Holder { 
    private static final AService theService = new AService(init); 
    } 

    private AService(int init) { 
    System.out.println("AService instance initialized with " + init); 
    } 

    public static AService instance(int init) { 
    AService.init = init; 
    return Holder.theService; 
    } 
} 

服務單例因此實例化被延遲,直到到實例第一呼叫(其可以採取額外的參數等),則可能執行更復雜的實例。根據您的項目初始化邏輯,您可能會將.instance(init)分爲.getFirstInstance(init).instance(),但這完全取決於您。