天天看點

C# 證明指令重排

using System;
using System.Threading;

public class TestInterlocak
{
    private int x = 0, y = 0, a = 0, b = 0;
    int count = 0;
    public void Exec()
    {
        while(true) 
        {
            //所有變量全部恢複初始值
            a = 0;
            b = 0;
            x = 0;
            y = 0;
             //計數加1
            count++;
            CountdownEvent countdownEvent  = new CountdownEvent(2);
            ThreadPool.SetMaxThreads(5, 100);
            ThreadPool.QueueUserWorkItem((state)=>{
                 a = 1;
                 y = b;
                countdownEvent.Signal();
            });
            ThreadPool.QueueUserWorkItem((state)=>{
                b = 1;
                x = a;
                countdownEvent.Signal();
            });
            countdownEvent.Wait();
            //此時,上面的兩個線程已經執行完畢。如果代碼在執行過程中都是
            //一行一行的代碼順序執行的,那麼上面兩個線程無論是怎樣的先後執行
            //順序,a=1和b=1,這兩句代碼作為第一行代碼,總有一句是最先執行的,
            //也就是說,到最後x或y肯定都不為0。如果到最後x和y都同時為0了,那
            //麼根據反證法原理,代碼在執行過程中,有可能并不絕對按照代碼
            //順序依次執行,當然也就發生了指令重排,代碼執行中存在指令重排
            //的情況也就得到了證明

            //如果x和y都等于0了,就輸出結果(如果Java代碼真的按照順序一句一句
            //執行的話,是絕對不可能出現x和y同時為0的)
            if (x == 0 && y == 0) 
            {
                //指令重排輸出語句
                String message = "第" + count + "次出現指令重排,x=" + x + ",y=" + y;
                //列印,證明完畢
                System.Console.Error.WriteLine(message);
                //結束程式
                break;
            }
            Thread.Sleep(200);
        }
    }
}