В коде, подобном следующему, если Proc1 и Proc2 выполняются одновременно на разных процессорах, возможно ли для ThingVal2 получить значение, отличное от 5 (например, ноль)?
Class SimpleThing
Public X As Integer
Sub New(ByVal value As Integer)
X = value
End Sub
End Class
Class ConcurrencyTest
Dim Thing1 As New SimpleThing(5)
Dim Thing2 As New SimpleThing(0)
Dim ThingRef As SimpleThing = Thing1
Dim ThingVal1, ThingVal2 As Integer
Sub Proc1()
Thing2.X = 5
Threading.Thread.MemoryBarrier()
ThingRef = Thing2
End Sub
Sub Proc2()
ThingVal1 = Thing2.X
ThingVal2 = ThingRef.X
End Sub
End Class
Я знаю, что в слабой модели, такой как IA64, существует реальная возможность того, что Proc2 может увидеть ThingRef как измененный, но не увидит поле X Thing2 как сделавшее это. Существует ли такой риск для приложения .Net, работающего на x86 или x64? Если Proc1 создал новый экземпляр SimpleThing, установите его поле X равным 5, а затем установите ThingRef для указания на него, будет ли этого достаточно, чтобы избежать опасности, или возможно, что новая вещь будет размещена в строке кэша, которая было передано что-то еще, что поток Proc2 получил доступ?
Распространенная парадигма с многопоточным кодом - это создание неизменяемого объекта и установка изменяемой ссылки для указания на него (возможно, с использованием Interlocked.CompareExchange). Всегда ли безопасно в x86 / x64 читать неизменяемый тип без учета многопоточности или это может вызвать проблемы? Если последнее, что является предпочтительным способом в vb.net, чтобы гарантировать надежное поведение?
Кроме того, есть ли способ указать, что код должен выполняться таким образом, чтобы такие проблемы не возникали (например, ограничение выполнения одним ядром на чем-то вроде IA64, которое иначе не могло бы гарантировать правильную работу)?