采取以下示例:
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> objects
在Main()
中实例化,同样适用于Main()
同时多次调用的任务。
答案 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;内存区域中,因此有实例变量),这不是线程安全的。