class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);
    static bool change = false;    static void Main()
    {
        Console.WriteLine("Main starting.");
        ThreadPool.QueueUserWorkItem(new WaitCallback(WorkMethod), autoEvent);        while (!change)
        {
            // Wait for work method to signal.
            if (autoEvent.WaitOne(500, false))
            {
                Console.WriteLine("Work method signaled.");
            }
            else
            {
                Console.WriteLine("Timed out waiting for work method to signal.");
            }
        }
        Console.WriteLine("Main ending.");
    }    static void WorkMethod(object stateInfo)
    {
        Console.WriteLine("Work starting.");        for (int i = 0; i < 10; i++)
        {
            // Simulate time spent working.
            Thread.Sleep(new Random().Next(100, 1000));
            // Signal that work is finished.
            //Console.WriteLine("Work ending.");
            ((AutoResetEvent)stateInfo).Set();
        }        change = true;
    }
}
在这段代码中,change 变量无论是否设成 volatile,主程序都可以在循环 10 次之后退出,为什么呢?我可是在另外一个线程中改变 change 字段的值的呀。怎么会这样?!

解决方案 »

  1.   

    static bool change = false;
      设置成静态的会有问题
      

  2.   

    Volatile 
    volatile关键字用于定义一个变量,这个变量跨多个线程修改而不被lock(虽然我们大部分的时间锁定它们)。 volatile变量不受编译器优化,因此我们将获得该变量的所有的时间最新的值。见下面的例子:
     public volatile int i;
     Thread th = new Thread(new ThreadStart(VolatileInvoke));
     th.Start();
     Thread.Sleep(5000); //Holds current Thread for 5 seconds.
     MessageBox.Show("Value of i : " + i);
     th.Abort();
      
     private void VolatileInvoke()
     {
        while (true)
        {
              i++;
        }
     } 
    线程启动,volatile整数的值增加1,直到它被主线程中止。
    注意:Volatile类型没有线程优化。
      

  3.   

    WorkMethod本身就得循环10次  没有加change变量的判断 
    main 里的循环才会退出  但是注意Work得循环完才能退出
    你的测试结果说明olatile起作用
      

  4.   

    不明白楼主为什么觉得这个结果奇怪,在这个例子里change变量是否volatile都没有关系的吧?你就算在另一个先程改变change的值,这个值也还是WaitOne.change这个变量啊,主线程也是判断的这个变量啊,要是你在另一个线程改了change的值主线程还退不出来那就真奇怪了。
    volatile 关键字表示字段可能被多个并发执行线程修改。在这里好像没啥意义吧,你反正也只在Work线程里改过它的值啊。
      

  5.   

    不好意思,这么长时间没有来回复我这段代码好像是从 MSDN 上找来的,具体是哪里的我忘了,总觉得奇怪,如果是没有 volatile 关键字的话,照理说,应该是不能退出循环才对。但是加和不加 volatile 关键字都是一样的结果,这就令我感到很奇怪。那如果我想在有 volatile 字段的时候,主线程能循环退出;没有的时候无法退出,这个我应该怎么写?谢谢。