英文好的,可跳過,直接打開底部的“參考“鏈接。
代碼變序--reordering of memory Operations
大概4年前,閱讀了這篇文章后http://www.albahari.com/threading/,我就自我滿足,多線程編程不過就是用那些工具而已。
今天,讀了一篇文章后,http://msdn.microsoft.com/en-us/magazine/jj863136.aspx,才發(fā)現(xiàn)C#代碼是可以變序的(上面的文章也提到了,忘得一干二凈)。
舉例,你寫出如下的代碼
JIL運(yùn)行時的代碼卻可以像這樣(不是IL代碼哦,IL編譯出代碼與源代碼是一致的)
這個坑爹的JIL優(yōu)化,如果不注意,可能就不會抓住bug所在。底部有我寫的再現(xiàn)方法。先別運(yùn)行程序,試試猜猜結(jié)果有幾種可能。
總結(jié):浮躁+記憶力差是很致命的,必須要找適合自己的工作方式。深入理論上理解+上手驗證,這樣才算消化,也不容易忘。
不重復(fù)造輪子,更不能重復(fù)學(xué)習(xí)。
參考:
http://msdn.microsoft.com/en-us/magazine/jj863136.aspx
http://msdn.microsoft.com/en-us/magazine/jj883956.aspx
class PRogram { static void Main(string[] args) { DataInit di = new DataInit(); new Thread(() => { di.Init(); }) { IsBackground = true }.Start(); new Thread(() => { di.Print(); }) { IsBackground = true }.Start(); Console.WriteLine("Running... Press enter to quit"); Console.ReadLine(); } } public class DataInit { private int _data = 0; private bool _initialized = false; //準(zhǔn)備些無用的field private char _c = '0'; private int _data1 = 0; private int _data2 = 0; private int _data3 = 0; private int _data4 = 0; public void Init() { _data = 42; // Write 1 _initialized = true; // Write 2 //下面的field賦值是用來觸發(fā)JIL 優(yōu)化的,如何觸發(fā)的原理,我不知道:(。 ///*try屏蔽下面的代碼,結(jié)果很可能就是42了 _c = '0'; _data1 = 0; _data = 0; _data2 = 0; _data3 = 0; _data4 = 0; } public void Print() { Console.WriteLine(_data); Console.WriteLine(_initialized); if (_initialized) { Console.WriteLine(_data); //should 42,有時候確是0 } else { Console.WriteLine("Not initialized"); } } }
新聞熱點
疑難解答