真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Lazy<T>的使用方式(可實(shí)現(xiàn)單例模式)

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

目前創(chuàng)新互聯(lián)公司已為上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、江城網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("MyClass對象創(chuàng)建,其標(biāo)識:{0}", this.GetHashCode());
        }
    }
 static void Main(string[] args)
        {
            Console.WriteLine(DateTime.Now);
            Lazy lazyObj = new Lazy();
            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());
         }

得到結(jié)果為:

Lazy<T>的使用方式(可實(shí)現(xiàn)單例模式)

可以看到,雖然在25秒的時候,聲明了 Lazy對象,但是MyClass對象的構(gòu)造函數(shù)并沒有馬上調(diào)用。

程序延遲2秒后,打印lazyObj.Value中的MyClass對象的HashCode的時候,程序發(fā)現(xiàn)MyClass對象還未創(chuàng)建,才去創(chuàng)建,調(diào)用MyClass的構(gòu)造函數(shù)。一旦創(chuàng)建完畢后,之后再次調(diào)用lazyObj.Value中的MyClass對象,也不會再去創(chuàng)建該對象。

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

在多線程環(huán)境下:

創(chuàng)建Lazy對象的時候,使用它的重載構(gòu)造函數(shù)之一:

public Lazy(Func valueFactory, LazyThreadSafetyMode mode);

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

None

PublicationOnly

ExecutionAndPublication

如下一段測試代碼:

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

當(dāng)Mode參數(shù)為LazyThreadSafetyMode.None時,得到的結(jié)果如下:

Lazy<T>的使用方式(可實(shí)現(xiàn)單例模式)

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

當(dāng)Mode參數(shù)為LazyThreadSafetyMode.PublicationOnly時,得到的結(jié)果如下:

Lazy<T>的使用方式(可實(shí)現(xiàn)單例模式)

可能每次運(yùn)行的結(jié)果不同,但這次運(yùn)行中可以看到,MyClass的構(gòu)造函數(shù)被運(yùn)行了3次,但是即使有3個對象創(chuàng)建了,在每次調(diào)用該對象時,只使用其中的一個對象。(不確定使用的是最先生成的那個對象,因?yàn)闇y試的時候,發(fā)現(xiàn)有時候使用的對象是后生成的。不過根據(jù)本人理解應(yīng)該是使用最先生成的對象,由于在并發(fā)過程中,最先生成的對象不一定最先打印出來)

當(dāng)Mode參數(shù)為LazyThreadSafetyMode.ExecutionAndPublication時,得到的結(jié)果如下:

Lazy<T>的使用方式(可實(shí)現(xiàn)單例模式)

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


文章標(biāo)題:Lazy<T>的使用方式(可實(shí)現(xiàn)單例模式)
文章地址:http://weahome.cn/article/gicdhs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部