.Net POCO многопоточный? - PullRequest
       24

.Net POCO многопоточный?

5 голосов
/ 10 апреля 2011

Этот вопрос может показаться немного странным, но он связан с возможными проблемами видимости.Вопрос вдохновлен случаем на языке программирования Java (> jdk5), рассмотрим:

public class InmutableValue {
  private int value;
  public InmutableValue(int value) {this.value = value;}
  public int getValue() {return value;}
}

Несмотря на противоположное мнение, класс выше не является потокобезопасным.В многопоточной среде «значение» не гарантируется для других потоков.Чтобы сделать его потокобезопасным, нам нужно применить правило «до того, как это произойдет».Это можно сделать, отметив поле 'final'.

. Этот случай заставил меня задуматься, верно ли то же самое для среды выполнения .Net.Возьмем, к примеру:

public class InmutableValue {
  private int value;
  public InmutableValue(int value) {this.value = value;}
  public int Value { get{return value;}}
} 

Насколько я знаю, пометка поля значения как «только для чтения» не дает тех же гарантий, что и «финал» для java (но я могу быть ужасно неправ, надеюсь),Так нужно ли нам помечать поля как «изменчивые» (или использовать барьеры памяти и т. Д.), Чтобы обеспечить видимость другим потокам?Или применяются другие правила, обеспечивающие видимость?

Ответы [ 2 ]

2 голосов
/ 10 апреля 2011

Вы, наверное, беспокоитесь о ядрах процессора со слабой моделью памяти, такой как Alpha и Titanium.Имеет буфер записи в память, который может переупорядочивать записи в память, позволяя записать ссылку на объект до значения поля value .Возможно, вдохновленный блогом Рэймонда Чена?

Вы упускаете важную деталь.Чтобы создать многопоточную гонку, должно быть два потока, которые оба используют ссылку на объект.Один, который создает объект и сохраняет ссылку, другой, который использует эту ссылку. То, что принципиально небезопасно, доступ к ссылке на общий объект должен быть синхронизирован.Код синхронизации (например, оператор lock ) также обеспечивает сброс буфера обратной записи.Что препятствует тому, чтобы поток, который читает свойство, когда-либо видел устаревшее значение.

1 голос
/ 10 апреля 2011

В любом случае, ключевое слово readonly гарантирует, что поле будет назначено в конструкторе, а не где-либо еще (внутри класса).

И поскольку конструктор является поточно-ориентированным в общем смысле , созданный объект вернет то же значение:

static ImmutableValue imv = new ImmutableValue(123);

// thread 1, object is not created
imv.Value; // NullReferenceException, as usually

// thread 2, object is created
imv.Value; //123

// thread 3, object is created
imv.Value; //123

Для редактирования поля private необходимо использовать Reflection, и да, вам нужно будет заблокировать объект во время выполнения такого кода, чтобы гарантировать замораживание всех потоков, которые пытаются прочитать значение в данный момент.

...