以下C#代码线程是否安全?

前端之家收集整理的这篇文章主要介绍了以下C#代码线程是否安全?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试学习C#中的线程.今天我在 http://www.albahari.com/threading/播种以下代码
class ThreadTest
{
  bool done;

  static void Main()
  {
    ThreadTest tt = new ThreadTest();   // Create a common instance
    new Thread (tt.Go).Start();
    tt.Go();
  }

  // Note that Go is now an instance method
  void Go() 
  {
     if (!done) { done = true; Console.WriteLine ("Done"); }
  }
}

在Java中,除非将“完成”定义为volatile,否则代码将不安全. C#内存模型如何处理这个问题?

伙计们,谢谢大家的答案.非常感激.

解决方法

好吧,有明显的竞争条件,他们都可以看到做错和执行if身体 – 无论记忆模型如何都是如此.完成volatile并不会解决这个问题,也不会在Java中修复它.

但是,是的,在一个线程中进行的更改可能会发生,但在另一个线程中不可见.这取决于cpu架构等.作为我的意思的一个例子,考虑这个程序:

using System;
using System.Threading;

class Test
{
    private bool stop = false;

    static void Main()
    {
        new Test().Start();
    }

    void Start()
    {
        new Thread(ThreadJob).Start();
        Thread.Sleep(500);
        stop = true;
    }

    void ThreadJob()
    {
        int x = 0;
        while (!stop)
        {
            x++;
        }
        Console.WriteLine("Counted to {0}",x);
    }
}

虽然在我当前的笔记本电脑上这已经终止,我已经使用了其他机器,其中几乎完全相同的代码将永远运行 – 它永远不会“看到”更改停止在第二个线程中.

基本上,我试图避免编写无锁代码,除非它使用由真正了解其内容的人提供的更高级别的抽象 – 比如.NET 4中的Parallel Extensions.

有一种方法可以使用Interlocked使这段代码无锁,并且很容易纠正.例如:

class ThreadTest
{
  int done;

  static void Main()
  {
    ThreadTest tt = new ThreadTest();   // Create a common instance
    new Thread (tt.Go).Start();
    tt.Go();
  }

  // Note that Go is now an instance method
  void Go() 
  {
     if (Interlocked.CompareExchange(ref done,1,0) == 0) 
     {
         Console.WriteLine("Done");
     }
  }
}

这里,值的更改和测试将作为一个单元执行:如果当前为0,则CompareExchange仅将值设置为1,并返回旧值.因此,只有一个线程会看到返回值为0.

另外要记住的一点是:你的问题很模糊,因为你还没有定义“线程安全”的含义.我已经猜到了你的意图,但你从来没有说清楚.阅读this blog post by Eric Lippert – 非常值得.

猜你在找的C#相关文章