91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Lazy<T>的使用方式(可實現單例模式)

發布時間:2020-06-11 19:16:46 來源:網絡 閱讀:2396 作者:cnn237111 欄目:編程語言

Lazy<T>是延遲對象,通過它可以延遲創建T對象,也就是說,雖然已經聲明了對象,但是實際上只有在使用T對象的時候,才會去創建這個對象。如下代碼:

class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("MyClass對象創建,其標識:{0}", this.GetHashCode());
        }
    }
 static void Main(string[] args)
        {
            Console.WriteLine(DateTime.Now);
            Lazy<MyClass> lazyObj = new Lazy<MyClass>();
            Thread.Sleep(2000);//等待2秒鐘
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("MyClass對象的HashCode={0}", lazyObj.Value.GetHashCode());
            Console.WriteLine("MyClass對象的HashCode={0}", lazyObj.Value.GetHashCode());
            Console.WriteLine("MyClass對象的HashCode={0}", lazyObj.Value.GetHashCode());
            Console.WriteLine("MyClass對象的HashCode={0}", lazyObj.Value.GetHashCode());
         }

得到結果為:

Lazy<T>的使用方式(可實現單例模式)

可以看到,雖然在25秒的時候,聲明了 Lazy<MyClass>對象,但是MyClass對象的構造函數并沒有馬上調用。

程序延遲2秒后,打印lazyObj.Value中的MyClass對象的HashCode的時候,程序發現MyClass對象還未創建,才去創建,調用MyClass的構造函數。一旦創建完畢后,之后再次調用lazyObj.Value中的MyClass對象,也不會再去創建該對象。

在單線程的環境下,使用Lazy的意義也不是很明顯。

在多線程環境下:

創建Lazy對象的時候,使用它的重載構造函數之一:

public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode);

參數valueFactory是一個委托,通過他來創建T對象。mode則是線程安全性模式。是一個枚舉值,有三種值:

None

PublicationOnly

ExecutionAndPublication

如下一段測試代碼:


class Program
    {
        static void Main(string[] args)
        {
             Lazy<MyClass> lazyObj = new Lazy<MyClass>(() => { return new MyClass(); }, LazyThreadSafetyMode.None);//此處修改mode的參數(None,PublicationOnly,ExecutionAndPublication),看對程序有何影響
            for (int i = 0; i < 10; i++)
            {
                Thread th = new Thread(() => { Console.WriteLine("線程調用對象{0}", lazyObj.Value.GetHashCode()); });
                th.Start();
            }
        }
    }
    class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("MyClass對象創建,其標識:{0}", this.GetHashCode());
        }
    }

當Mode參數為LazyThreadSafetyMode.None時,得到的結果如下:

Lazy<T>的使用方式(可實現單例模式)

這錯誤原因是沒有創建MyClass實例前,就有線程去訪問對象的GetHashCode()方法了。這也說明了如果選用LazyThreadSafetyMode.None,那就不保證線程在訪問Lazy對象的lazyObj.Value前先創建對象。這種情況下,當有些線程在啟動前,很幸運的,該對象已經創建了,有些線程啟動前則很不幸,對象并沒有創建。因此會出現上面的那種異常。

當Mode參數為LazyThreadSafetyMode.PublicationOnly時,得到的結果如下:

Lazy<T>的使用方式(可實現單例模式)

可能每次運行的結果不同,但這次運行中可以看到,MyClass的構造函數被運行了3次,但是即使有3個對象創建了,在每次調用該對象時,只使用其中的一個對象。(不確定使用的是最先生成的那個對象,因為測試的時候,發現有時候使用的對象是后生成的。不過根據本人理解應該是使用最先生成的對象,由于在并發過程中,最先生成的對象不一定最先打印出來)

當Mode參數為LazyThreadSafetyMode.ExecutionAndPublication時,得到的結果如下:

Lazy<T>的使用方式(可實現單例模式)

使用LazyThreadSafetyMode.ExecutionAndPublication,保證了對象只被創建一次。基于這個特性,可以使用LazyThreadSafetyMode.ExecutionAndPublication方式,實現在多線程下的單例模式。但是要注意:此時Lazy對象僅保證多個線程訪問的是同一個對象,但不保證多線程訪問對象時候是否同步,因此,如果要確保多線程訪問同步訪問同一個對象,最好還是采取lock等方式。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武强县| 龙胜| 田阳县| 汾阳市| 合山市| 都兰县| 宝鸡市| 若羌县| 新乡市| 微博| 罗定市| 启东市| 富平县| 郸城县| 玛纳斯县| 遂溪县| 米脂县| 库伦旗| 松滋市| 类乌齐县| 祁门县| 华蓥市| 陇西县| 滦南县| 阿尔山市| 陆川县| 临武县| 葵青区| 闵行区| 鄂伦春自治旗| 洪洞县| 视频| 刚察县| 镇宁| 珠海市| 内乡县| 大悟县| 济源市| 威宁| 江西省| 潼关县|