static关键字如何影响线程安全?为什么?

时间:2017-03-31 17:45:59

标签: c# .net multithreading c#-4.0 task-parallel-library

采取以下示例:

List<MyObject> objects = new List<MyObject();

示例#1:

static class MyClass1
{
    static void MyMember(List<MyObject> objects) { objects.Add(new MyObject); }
}

示例#2:

class MyClass2
{
    void MyMember(List<MyObject> objects) { objects.Add(new MyObject); }
}

示例#3:

static MyClass3 myClass3 = new MyClass3();
class MyClass3
{
    void MyMember(List<MyObject> objects) { objects.Add(new MyObject); }
}

然后调用

 Task.Factory.StartNew(() =>
 {
    MyClass1.MyMember(objects);
 });

 MyClass2 myClass2 = new MyClass2();
 Task.Factory.StartNew(() =>
 {
    myClass2.MyMember(objects);
 });

 static MyClass3 myClass3 = new MyClass3();
 Task.Factory.StartNew(() =>
 {
    myClass3.MyMember(objects);
 });

假设应用程序只有这些示例中的一个,并且同时多次调用Task

您可以将此视为一个控制台应用,其中List<MyObject> objectsMain()中实例化,同样适用于Main()同时多次调用的任务。

2 个答案:

答案 0 :(得分:1)

这取决于方法的内部逻辑。目前(空实现)它们都是线程安全的。

UPD:

现在它们都不是线程安全的。我想指出static关键字本身并不提供任何“魔力”。可能是因为.NET基类库中的常见约定而使您感到困惑,以使所有静态成员都是线程安全的,并且所有实例成员都不是线程安全的。虽然这是事实,但BCL的开发人员决定遵循这一惯例。在您自己的代码中,static在您自己实现之前不提供任何线程安全性。

答案 1 :(得分:1)

要使示例#1起作用,您必须拥有

static class MyClass1
{
    static List<MyObject> objects = new List<MyObject();
    static void MyMember() { objects.Add(new MyObject); }
}

以便MyMember访问对象。因为只有一个静态类的数据成员实例(由于无法构造静态类,所以必须全部是静态的(它不像引用变量那样在堆上动态分配,而是分配在一个单独的&#34;全局&#34;内存区域中,因此有实例变量),这不是线程安全的。

相关问题