在C#中进行线程化,值类型和引用类型澄清?

时间:2021-02-19 16:10:22

After reading Jon Skeet article , and this article from msdn , I still have a question

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

Let's say I have this code :

假设我有这个代码:

  MyPerson mp = new MyPerson(); //Field

  int g=0; //Field

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

Now let's say I have 2 threads. which runs DoWork. ( let's ignore for now , race conditions)

现在让我们说我有两个主题。运行DoWork。 (让我们暂时忽略,竞争条件)

  • Will they both see the same g or each thread will have its own item ? ? ( value )

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

  • Will they both see the same mp or each thread will have its own item ?? ( instance )

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

  • Will they both see the same i or each thread will have its own item ? ( value )

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

  • Will they both see the same mp2 or each thread will have its own item ? ( instance )

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

  • if they both see the same , why would I need static ?

    如果他们都看到相同,为什么我需要静电?

I've searched a lot about this topic , and couldn't find any article which states : Different Threads ,ref types and value types... )

我搜索了很多关于这个主题的内容,但找不到任何文章说明:不同的主题,引用类型和值类型...)

2 个解决方案

#1


13  

Neither thread simply "runs DoWork"; they run DoWork on a particular object. If the two threads are created targeting different instances, then mp and g will be completely separate fields. If the two threads are created targeting the same instance, then mp and g will be shared but it is not guaranteed that the threads will see changes made by the other thread unless you use synchronization or volatile access.

两个线程都没有“运行DoWork”;他们在特定对象上运行DoWork。如果针对不同的实例创建了两个线程,则mp和g将是完全独立的字段。如果创建了针对同一实例的两个线程,则将共享mp和g,但不保证线程将看到另一个线程所做的更改,除非您使用同步或易失性访问。

For example:

例如:

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

vs

VS

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

The local variables i and mp2 are strictly specific to each thread.

局部变量i和mp2严格地特定于每个线程。

Additional note: even if they are separate fields/locals, if some of the code in the ... later reassigns mp or mp2 to refer to the same object, then they will be squabbling over the same object; the same synchronization / volatile rules will apply.

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

#2


3  

The variables g and mp are 'global' to the containing class, so these will be the same objects seen by both threads. i is a local variable that is declared in the DoWork event; subsequently this will only be 'visible' to the background/alternative thread.

变量g和mp对于包含类是“全局的”,因此它们将是两个线程看到的相同对象。我是在DoWork事件中声明的局部变量;随后这只会对后台/替代线程“可见”。

They don't 'see' the same, so the static keyword in this case has no relevence.

他们没有“看到”相同,所以在这种情况下静态关键字没有相关性。

I hope this helps.

我希望这有帮助。

#1


13  

Neither thread simply "runs DoWork"; they run DoWork on a particular object. If the two threads are created targeting different instances, then mp and g will be completely separate fields. If the two threads are created targeting the same instance, then mp and g will be shared but it is not guaranteed that the threads will see changes made by the other thread unless you use synchronization or volatile access.

两个线程都没有“运行DoWork”;他们在特定对象上运行DoWork。如果针对不同的实例创建了两个线程,则mp和g将是完全独立的字段。如果创建了针对同一实例的两个线程,则将共享mp和g,但不保证线程将看到另一个线程所做的更改,除非您使用同步或易失性访问。

For example:

例如:

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

vs

VS

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

The local variables i and mp2 are strictly specific to each thread.

局部变量i和mp2严格地特定于每个线程。

Additional note: even if they are separate fields/locals, if some of the code in the ... later reassigns mp or mp2 to refer to the same object, then they will be squabbling over the same object; the same synchronization / volatile rules will apply.

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

#2


3  

The variables g and mp are 'global' to the containing class, so these will be the same objects seen by both threads. i is a local variable that is declared in the DoWork event; subsequently this will only be 'visible' to the background/alternative thread.

变量g和mp对于包含类是“全局的”,因此它们将是两个线程看到的相同对象。我是在DoWork事件中声明的局部变量;随后这只会对后台/替代线程“可见”。

They don't 'see' the same, so the static keyword in this case has no relevence.

他们没有“看到”相同,所以在这种情况下静态关键字没有相关性。

I hope this helps.

我希望这有帮助。