2016-01-20 91 views
0

我在使用Lucene IndexWriter的一個Java EE Beans中遇到了「線程安全」方法調用的問題。Singleton Pattern和Synchronized有什麼區別

我不確定我是否應該通過實施Singleton模式,或者如果它是足夠的關鍵字​​添加到我的bean的方法解決我的問題。

任何人都可以解釋究竟是什麼區別?

+1

除非你澄清你的問題**,否則很難推薦。兩者都是兩個不同的東西(儘管有些關聯),所以列出你的代碼或者詳細說明你的問題。 –

+0

如果速度對於那個特定方法來說不是一個大問題(例如方法非常快),那麼,單身模式會讓生活變得容易 – nafas

+0

您的意思是「線程安全」嗎? – Ekrem

回答

2

單例創建一個類的一個實例。只要它本身沒有被引用。

作爲非線程安全方法的一個例子:

public class Singleton { 

    private static Singleton instance; 
    private Singleton() {} 

    public static Singleton getInstance() { 
    if (Singleton.instance == null) { 
     Singleton.instance = new Singleton(); 
    } 
    return Singleton.instance; 
    } 
} 

這樣做的問題是:如果一個以上的線程在第一次同時執行的getInstance,的Singleton的構造函數被調用多於一旦。所以單身人士不會是單身人士,而且隨後的錯誤很難被發現。一個線程安全的方法

例子:

public class Singleton { 

    private static Singleton instance; 
    private Singleton() {} 
    public static synchronized Singleton getInstance() { 
    if (Singleton.instance == null) { 
     Singleton.instance = new Singleton(); 
    } 
    return Singleton.instance; 
    } 
} 

有關此方法壞事是,對於每一個訪問getInstance方法被調用(所以一個線程可以阻止其他人)。

最後但並非最不重要的同步版本:

類變量的
public class Singleton { 
    private static final class InstanceHolder { 
    static final Singleton INSTANCE = new Singleton(); 
    } 
    private Singleton() {} 
    public static Singleton getInstance() { 
    return InstanceHolder.INSTANCE; 
    } 
} 

初始化是隱式類加載器同步。通過使用內部類Singleton-Constructor,它僅在getInstance方法的內部類的初始化期間被調用。

我希望這可以幫助你。如果您需要更多信息,請發表評論,並對我英語不好的英語感到抱歉。

+0

_在這種情況下,可能有多個線程在同一個實例中工作。聽起來像是一個問題,但是這不是第一次使用單例的原因嗎?第一個例子中**真正的問題**非常不同但非常糟糕:如果多個線程第一次同時執行'getInstance',則Singleton'的構造函數被多次調用(這很可能發生,如果單身人士的建設不平凡)。所以單身人士不會是單身人士,而且隨後的錯誤很難被發現**。 –

+0

這就是爲什麼我不會推薦使用第一個例子。正如你所看到的,當多個Thread使用它時可能會產生問題。作爲一個例子,如果進度需要在構造函數中進行初始化。然後他啓動進程,並在另一個線程希望訪問的同時,在初始化時,secend線程將獲得一個半燒成的實例。像這樣的錯誤的問題是,他們很難找到,就像你傷心並且你沒有在同一時間得到它們一樣。 –

+0

我不這麼認爲,第一種解決方案有任何問題。第一種解決方案解決了問題所要求的問題,即使線程安全。雖然,它會導致阻塞其他線程的性能成本,但肯定會根據問題的工作。如果我的理解錯誤,請糾正我。 第二種解決方案並不總是令人滿意的,因爲大多數時候,我們的初始化代碼都需要一些在類級別初始化時不可用的資源,否則第二種解決方案也適用。 –

0

單例模式是跨jvm或應用程序實例的一個對象概念,而synchronized是java中用於相互排斥的關鍵字。請詳細說明你的問題。