第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

在多線程程序中未讀取正確的屬性值

在多線程程序中未讀取正確的屬性值

C#
幕布斯6054654 2023-06-25 13:54:41
我遇到了一種情況,我不確定為什么我在多個(gè)線程中沒(méi)有從屬性中讀取正確的屬性值。我編寫了一個(gè)小型控制臺(tái)應(yīng)用程序來(lái)說(shuō)明這種情況class Program{    private static Test MyObject;    static void Main(string[] args)    {        MyObject = new Test();        Task.Run(() =>        {            var obj = MyObject as Test;            Console.WriteLine("1: " + obj.MyValue);            Update("Thread1");            Console.WriteLine("2: " + obj.MyValue);        });        Task.Run(() =>        {            var obj = MyObject as Test;            Console.WriteLine("3: " + obj.MyValue);            Thread.Sleep(100);            Update("Thread2");            Console.WriteLine("4: " + obj.MyValue);        });        void Update(string val)        {            lock (MyObject)            {                MyObject.MyValue = val;            }        }        Thread.Sleep(400);        Console.WriteLine("5: " + MyObject.MyValue);    }}class Test{    public string MyValue { get; set; }}運(yùn)行上面的行我得到這個(gè)輸出1:2: Thread13:4: Thread25: Thread2我的期望是“3:”應(yīng)該始終顯示“3:Thread1”,因?yàn)橥粚?duì)象已較早更新。但事實(shí)并非如此,我不確定我在這里缺少什么......有人可以解釋一下嗎?只是一個(gè)小注意...如果您運(yùn)行代碼并得到不同的順序,請(qǐng)重新運(yùn)行它...我只對(duì)上面的順序感興趣。
查看完整描述

1 回答

?
慕田峪7331174

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超13個(gè)贊

有幾件事:

  1. 您的Update()方法將寫入同步屬性MyValue,但對(duì)讀取不執(zhí)行任何操作。因此,運(yùn)行時(shí)可以自由地使用對(duì)象的緩存值。這不太可能與您觀察到的輸出有任何關(guān)系,因?yàn)閷?shí)際上您不太可能看到這一點(diǎn),尤其是在 x86 硬件上。但…

  2. 更重要的是,您的代碼所展示的只是輸出順序可能會(huì)產(chǎn)生誤導(dǎo)。該類Console具有同步功能以確保來(lái)自多個(gè)線程的一致輸出,但是代碼中沒(méi)有任何內(nèi)容可以確保如果按特定順序?qū)懭胼敵鲂?,則導(dǎo)致這些輸出行的代碼(例如讀取屬性)MyValue發(fā)生與這些輸出行的顯示順序相同。

換句話說(shuō),僅僅因?yàn)?em>控制臺(tái)"2:"在該行之前顯示了該行"3:",實(shí)際上并不意味著對(duì)的調(diào)用發(fā)生Update("Thread1")在對(duì)Console.WriteLine("3: " + obj.MyValue);

lock如果您想確保輸出行與程序中語(yǔ)句的執(zhí)行順序相匹配,您還需要使用語(yǔ)句來(lái)保護(hù)各個(gè)操作。

更具體地說(shuō),請(qǐng)考慮以下可能的代碼執(zhí)行順序:

thread 1                                      thread 2

--------                                      --------

                                              "value" parameter <= "3: " + obj.MyValue

Console.WriteLine("1: " + obj.MyValue);

Update("Thread1");

Console.WriteLine("2: " + obj.MyValue);

                                              Console.WriteLine(value);

Console.WriteLine()即,在第一個(gè)線程開(kāi)始其邏輯之前,第二個(gè)線程計(jì)算傳遞給的參數(shù)是完全合法的。但是,第一個(gè)線程也可以在第二個(gè)線程有機(jī)會(huì)實(shí)際調(diào)用該Console.WriteLine()方法之前搶占第二個(gè)線程。


如果發(fā)生這種情況,您會(huì)看到線程 1 的預(yù)期輸出順序,但線程 2 的輸出寫入該屬性的明顯過(guò)時(shí)版本MyValue,因?yàn)樗窃诰€程 1 運(yùn)行其任何邏輯之前檢索到的。


為了解決該特定場(chǎng)景,您可以使用lock呼叫WriteLine()。例如:


lock (MyObject) Console.WriteLine("1: " + obj.MyValue);

請(qǐng)注意,您需要將其放在每次調(diào)用Console.WriteLine(). 這將確保寫入控制臺(tái)的任何值都是調(diào)用時(shí)屬性的最新值。


查看完整回答
反對(duì) 回復(fù) 2023-06-25
  • 1 回答
  • 0 關(guān)注
  • 125 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)