什么是單例(Singleton)模式
Singleton指僅僅被實例化一次的類。Singleton通常被用來代表那些本質(zhì)上唯一的系統(tǒng)組件。
實現(xiàn)單例模式可以帶來如下好處:
- 某些類的創(chuàng)建比較頻繁,對于一個大型對象,這是一筆很大的開銷。
- 省去了new的操作,降低了系統(tǒng)內(nèi)存的使用頻率,減輕GC的壓力。
- 有些類是如交易系統(tǒng)引擎,控制著交易流程,如果系統(tǒng)中存在多個將會使系統(tǒng)混亂。
經(jīng)典單例模式的實現(xiàn)
- 使用一個private的構(gòu)造器避免直接調(diào)用類的構(gòu)造。
- 使用一個公共的接口來取得單例。
ClassicSingletonTest.java
public class ClassicSingletonTest
{
public static void main(String[] args)
{
Singleton singleton1 = Singleton.getInstance();
Singleton Singleton2 = Singleton.getInstance();
if (singleton1 == singleton1)
{
System.out.println("Equal");
}
}
}
class Singleton
{
public static Singleton instance = null;
private Singleton(){};
public static Singleton getInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
這個單例模式使用了懶加載(lazy initialization),單例只有在第一次調(diào)用getInstance()方法時才會被創(chuàng)建。懶加載確保了單例只會在被需要的時候創(chuàng)建。在上述例子中,我們可以看到Singleton的構(gòu)造器被設置成了private的,這意味著這個單例模式無法被繼承,所以最好的方法應該聲明此單例類為final。此外,經(jīng)典單例模式還存在以下幾點值得討論的地方:
- 當有多不同classloaders來加載這個單例類時,可能會出現(xiàn)多個實例。
- 如果單例類實現(xiàn)了序列化接口,當這個類被解序列化多次的時候可能會出現(xiàn)多個實例。
- 更重要的是,經(jīng)典單例模式不是線程安全的,當同時有多個線程調(diào)用getInstance()方法時,線程A進入了if語句塊,然后將CPU時間讓給線程B,線程B檢測到instance還是null,也進入到了if語句塊,這樣就會導致兩個實例的產(chǎn)生。