久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

算法55 Singleton(C/C++/C#)

 白雪~~~ 2012-04-02

題目:設計一個類,我們只能生成該類的一個實例,。

分析:只能生成一個實例的類是實現(xiàn)了Singleton模式的類型,。

由于設計模式在面向?qū)ο蟪绦蛟O計中起著舉足輕重的作用,在面試過程中很多公司都喜歡問一些與設計模式相關的問題,。在常用的模式中,,Singleton是唯一一個能夠用短短幾十行代碼完整實現(xiàn)的模式。因此,,寫一個Singleton的類型是一個很常見的面試題,。

事實上,要讓一個類型是能創(chuàng)建一個實例不是一件很難的事情,。我們可以把該類型的構造函數(shù)設為private,,這樣該類型的用戶就不能創(chuàng)建該類型的實例了。然后我們在給類型中創(chuàng)建一個靜態(tài)實例,。當用戶需要該類型的實例時,,我們就返回這個實例?;谶@個思路,,我們可以用C#寫出如下代碼:

// We can only get an instance of the class Singleton1. The instance

// is created when class Singleton1 is referenced at the first time

public sealed class Singleton1

{

private Singleton1()

{

}

private static Singleton1 instance = new Singleton1();

public static Singleton1 Instance

{

get

{

return instance;

}

}

}

由于類Singleton1 的實例是一個靜態(tài)變量,因此它會在該類型的第一次引用的時候被創(chuàng)建,,而不是第一次在調(diào)用Singleton1.get_Instance的時候被創(chuàng)建,。如果我們此時并不需要該實例,那么我們就過早地初始化該實例,,無論在內(nèi)存空間還是CPU時間上都是一種浪費,。

我們可以把上面的代碼稍作改動,就能實現(xiàn)在第一次調(diào)用Singleton_getInstance時候才會創(chuàng)建類型的唯一實例:

// We can only get an instance of the class Singleton2.

// The instance is created when we need it explicitly.

public sealed class Singleton2

{

private Singleton2()

{

}

private static Singleton2 instance = null;

public static Singleton2 Instance

{

get

{

if (instance == null)

instance = new Singleton2();

return instance;

}

}

}

我們在單線程環(huán)境下只能得到類型Singleton2的一個實例,,但在多線程環(huán)境下情況就可能不同了,。設想如果兩個線程同時運行到語句if (instance == null),而此時該實例的確沒有創(chuàng)建,,那么兩個線程都會創(chuàng)建一個實例,。此時,類型Singleton2就不在滿足模式Singleton的要求了,。

為了保證在多線程環(huán)境下我們還是只能得到類型的一個實例,我們應該在判斷實例是否已經(jīng)創(chuàng)建,,以及在實例還沒有創(chuàng)建的時候創(chuàng)建一個實例的語句上加一個同步鎖,。我們把Singleton2稍作修改就得到了如下代碼:

// We can only get an instance of the class Singleton3,

// even when there are multiple threads which are trying

// to get an instance concurrently.

public sealed class Singleton3

{

private Singleton3()

{

}

private static readonly object syncObj = new object();

private static Singleton3 instance = null;

public static Singleton3 Instance

{

get

{

lock (syncObj)

{

if (instance == null)

instance = new Singleton3();

}

return instance;

}

}

}

說明一下,由于C/C++沒有為線程同步提供直接的支持,。為了讓代碼顯得簡潔,,而不是讓大量的代碼在實現(xiàn)同步鎖而偏離了實現(xiàn)Singleton的主題,,本文的代碼用C#實現(xiàn)。

我們還是假設有兩個線程同時想創(chuàng)建一個實例,。由于在一個時刻只能有一個線程能得到同步鎖,。當?shù)谝粋€線程加上鎖時,第二個線程只能在等待,。當?shù)谝粋€線程發(fā)現(xiàn)實例還沒有創(chuàng)建時,,它創(chuàng)建出一個實例。接著第一個線程釋放同步鎖,。此時第二個線程可以加上同步鎖,,并運行接下來的代碼。由于此時實例已經(jīng)被第一個線程創(chuàng)建出來了,,第二個線程就不會重復創(chuàng)建實例了,。于是保證了我們只能得到一個實例。

但是類型Singleton3還不是完美,。由于我們每次調(diào)用Singleton3.get_Instance的時候,,都會試圖加上一個同步鎖。由于加鎖是一個非常耗時的操作,,在沒有必要的時候我們應該盡量避免這樣的操作,。

實際上,我們只是在實例還沒有創(chuàng)建之前需要加鎖操作,,以保證只有一個線程創(chuàng)建出實例,。而當實例已經(jīng)創(chuàng)建之后,我們已經(jīng)不需要再做加鎖操作了,。于是,,我們可以把上述代碼再作進一步的改進:

// We can only get an instance of the class Singleton4,

// even when there are multiple threads which are trying

// to get an instance concurrently. When the instance has

// been created, we don't need the lock any more.

public sealed class Singleton4

{

private Singleton4()

{

}

private static object syncObj = new object();

private static Singleton4 instance = null;

public static Singleton4 Instance

{

get

{

if (instance == null)

{

lock (syncObj)

{

if (instance == null)

instance = new Singleton4();

}

}

return instance;

}

}

}

我們只需要在最開始調(diào)用Singleton4_getInstance(可能來自一個線程,也可能來自多個線程)的時候需要加鎖,。當實例已經(jīng)創(chuàng)建之后,,我們就不再需要作加鎖操作,從而在后續(xù)調(diào)用Singleton4_getInstance時性能得到提升,。

關于第一種寫法的更多,,請參考http://en./wiki/Double-checked_locking。站在面試的角度,,本文的分析已經(jīng)足夠應付,。但如果想展示更多對多線程編程的理解,更深入地了解這個問題總是有益的,。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多