9

在阅读了 Jon Skeet的文章 和msdn 的这篇文章后,我还有一个问题

假设我有这个代码:

  MyPerson mp = new MyPerson(); //Field

  int g=0; //Field

  public void DoWork ()
   {
      int i;
      MyPerson mp2 = new MyPerson();  
      ...
   }

现在假设我有 2 个线程。哪个运行DoWork。(让我们暂时忽略竞争条件)

  • 他们会看到相同的g内容还是每个线程都有自己的项目?? ( 价值 )

  • 他们会看到相同的mp 内容还是每个线程都有自己的项目?( 实例 )

  • 他们会看到相同的i内容还是每个线程都有自己的项目?( 价值 )

  • 他们会看到相同的mp2内容还是每个线程都有自己的项目?( 实例 )

  • 如果他们都看到相同的东西,我为什么需要static

我已经搜索了很多关于这个主题的文章,但找不到任何文章指出:不同的线程,引用类型和值类型......)

4

2 回答 2

13

两个线程都不会简单地“运行DoWork”;它们DoWork 在特定对象上运行。如果两个线程是针对不同的实例创建的,那么mpg将是完全独立的字段。如果两个线程是针对同一个实例创建的,那么mpg将被共享,但不能保证线程会看到另一个线程所做的更改,除非您使用同步或volatile访问。

例如:

var obj = new SomeObject();
Thread thread1 = new Thread(obj.DoWork);
Thread thread2 = new Thread(obj.DoWork); // clearly targeting the same instance

对比

var obj = new SomeObject();
Thread thread1 = new Thread(obj.DoWork);
obj = new SomeObject();
Thread thread2 = new Thread(obj.DoWork); // targeting a different instance

局部变量imp2严格特定于每个线程。

附加说明:即使它们是单独的字段/本地,如果后面的某些代码...重新分配mpmp2引用同一个对象,那么它们将在同一个对象上争吵;将适用相同的同步/volatile规则。

于 2012-12-03T10:37:51.253 回答
3

变量gmp对包含的类是“全局的”,因此它们将是两个线程看到的相同对象。是在事件i中声明的局部变量;DoWork随后,这将仅对背景/替代线程“可见”。

他们没有“看到”相同的东西,因此static在这种情况下,关键字没有相关性。

我希望这有帮助。

于 2012-12-03T10:35:16.083 回答