1. 程式人生 > >考的好不好?-單例模式來解答

考的好不好?-單例模式來解答

全局 優勢 read 分析 技術 單例類 readonly 事情 釋放

版權聲明:本文為博主原創文章,未經博主同意不得轉載。 https://blog.csdn.net/huo065000/article/details/24486185

前言:

? ? ??從小就非常反感考試。由於每次考試完無論是誰,碰見你的第一句問候語就是:考試考得怎麽樣啊?期末成績出來了嗎?……所以從小就非常害怕成績單的出現,由於成績單僅僅要不出現,自己就能夠任意編篡,問自己考得怎麽樣?當然往好裏說吧!還行吧!挺好的……

? ? 由於考試考得好不好。是由自己內心來推斷的,考得好,我當然希望告訴他人;可是考得不好,我也不想讓他人知道。所以僅僅要蒙混過關就可!


? ? 這樣就談到了今天的主題-單例模式,某件事情我僅僅想讓他出現一次,而非每次點擊都出現,這就是所謂的實例化,實例化與否的過程事實上就是和考試考得好不好的過程一樣,應該由自己來推斷,要勇於承擔責任,這才是當今一代的學習楷模。

定義:

? ? ? ? ? ?單例模式:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

方法:

? ? ??通常我們能夠讓一個全局變量使得一個對象被訪問,但它不能防止你實例化多個對象。一個最好的辦法就是,讓類自身負責保存它的唯一實例。這個類能夠保證沒有其它實例能夠被創建。並且它能夠提供一個訪問該實例的方法。

結構圖:

技術分享圖片

優點:

1)保證唯一的實例 2)單例模式由於Singleton類封裝它的唯一實例,這樣它能夠嚴格地控制客戶如何訪問它以及何時訪問它,簡單點就是對唯一實例的受控訪問。

多線程單例:

? ? 多線程的程序中,多個線程同一時候訪問Singleton類,調用GetInstance()方法,會有可能造成創建多個實例的。 解決的方法:給進程加一把鎖來處理。

? ?Lock:是確保一個線程位於代碼的臨界區時,還有一個線程不進入臨界區。假設其它線程視圖進入鎖定的代碼,則它將一直等待(即被組織)直到該對象被釋放。 ? ? ??

 class Singleton
    {
        private static Singleton instance;
        //程序執行時創建一個靜態僅僅讀的進程輔助對象
        private static readonly object syncRoot = new object();
        private Singleton ()
        {
        }
        public static Singleton GetInstance()
        {
            lock (syncRoot )    //在同一個時刻加了鎖的那部分程序僅僅有一個線程能夠進入
            {
                if (instance ==null )
                {
                    instance = new Singleton();
                }
            }
            return instance;
        }
? ? ?這段代碼使得對象實例由最先進入的那個線程創建,以後的線程在進入時不會再去創建對象實例了。可是instance有沒有被創建過實例根本不知道,所以優化之後:
public static Singleton GetInstance()
        {
            if (instance == null)   //先推斷實例是否存在,不存在再加鎖處理
            {
                lock (syncRoot)    //在同一個時刻加了鎖的那部分程序僅僅有一個線程能夠進入
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }

構建方式:

餓漢式單例類
懶漢式單例類

? ? 懶漢式單例類在單例類被載入的時候。就實例化一個對象交給自己的應用。而懶漢式在調用取得實例方法的時候才會實例化對象。代碼例如以下: 懶漢式:
public sealed class Singleton  //阻止發生派生。而派生可能會添加實例
        {
            private static class Singleton
            {
                //在第一次引用類的不論什麽成員時創建實例。公共語言執行庫負責處理變量初始化
                private static readonly Singleton instance = new Singleton();
                private Singleton() { }
                public static Singleton GetInstance()
                {
                    return instance;
                }
            }
餓漢式:
public class Singleton  //阻止發生派生,而派生可能會添加實例
        {
            private static class Singleton=null ;
            {
                private Singleton() { }
                public static  synchronized synchronized GetInstance()
                {
                    if (Singleton ==null )
                    {
                        Singleton = new Singleton();
                    }
                    return instance;
                }
            }
? ? ??對於懶漢和餓漢的使用,由於餓漢式,即靜態初始化的方式,它是類一載入就實例化的對象,所以要提前占用系統資源。然而懶漢式又要面臨著多線程訪問的安全性問題,須要做雙重鎖定這種處理才幹夠保證安全。

所以至於使用哪種方式。應該取決於實際的需求。

可是從c#的角度來看。餓漢式單例類應能夠滿足我們的需求。

單例模式與靜態類

? ? ?總認為單例模式有點像一個有用類的靜態方法。那麽有些什麽差別呢?來細致分析一下: 1)單例模式相比靜態類的優勢:單例能夠繼承類,實現接口,而靜態類不能。單例能夠被延遲初始化。靜態類一般在第一次載入是初始化;單例類能夠被集成,他的方法能夠被覆寫。

2)靜態方法中產生的對象。會隨著靜態方法執行完成而而釋放掉。並且執行類中的靜態方法時,不會實例化靜態方法所在的類 3)在不存在比較復雜的事務管理。用Singleton比較好。




考的好不好?-單例模式來解答