2012-12-03 67 views
6

我希望看到在c#中實時使用Volatile關鍵字。但我無法展示最好的例子。下面的示例代碼在沒有Volatile關鍵字的情況下工作如何可能?什麼是在C#中的揮發性關鍵字的目的?

class Program 
{ 
    private static int a = 0, b = 0; 

    static void Main(string[] args) 
    { 
     Thread t1 = new Thread(Method1); 
     Thread t2 = new Thread(Method2); 

     t1.Start(); 
     t2.Start(); 

     Console.ReadLine(); 
    } 

    static void Method1() 
    { 
     a = 5; 
     b = 1; 
    } 

    static void Method2() 
    { 
     if (b == 1) 
      Console.WriteLine(a); 
    } 
} 

在上面的代碼中,我得到的值爲5.它如何工作,而不使用volatile關鍵字?

+1

它不起作用。由於您忘記使用'volatile',您希望獲得除5之外的其他值。然而,您獲得了5個。所以它不*工作,這是您期望將某些東西排除在外的。 (修復bug和神祕程序會消失,帶有線程bug的代碼幾乎不可能理解,只需修復它們並忘掉它。) –

+0

你能告訴我一個最好的易失性示例嗎? – Gun

+0

現在,沒有任何'volatile'關鍵字,沒有**保證**程序不會輸出'0'。它可能(有一天)輸出'0'。如果添加'volatile'關鍵字,它不能輸出'0',它只能給出_either_無輸出或''5'。 –

回答

11

volatile關鍵字告訴編譯器一個變量可以在任何時候改變,所以它不應該優化掉變量的讀寫。

考慮這樣的代碼:

int sum; 
for (var i = 0; i < 1000; i++) { 
    sum += x * i; 
} 

由於變量x沒有內循環改變,編譯器可能外循環讀取一次變量,只是使用在整個循環相同的值。

如果變量爲x爲volatile,則編譯器將在每次使用該變量時讀取該變量的值,因此如果在其他線程中更改該值,則會立即使用該新值。

2

如果您正確使用volatile,則您的代碼可以保證正常工作。如果您在代碼需要的地方遺漏了volatile,那麼大多數情況下它可能會正常工作,但不能保證,並且可能會在最大程度上受損時失敗。

瞭解代碼與線程競爭失敗或不失敗需要深入瞭解實現和平臺。這並不簡單,通常也不值得擔心。只要遵守規則,您的代碼就可以隨時工作。