Насколько потокобезопасны неизменяемые объекты?

Все говорят, что неизменяемые объекты являются потокобезопасными, но почему это?

следующий сценарий, работающий на многоядерном процессоре:

  • Ядро 1 считывает объект в ячейке памяти 0x100 , и он кэшируется в кэше L1 / L2 ядра 1;
  • GC собирает этот объект в этой ячейке памяти, потому что он стал подходящим и 0x100 становится доступным для новых объектов;
  • Ядро 2 выделяет (неизменяемый) объект, который расположен по адресу 0x100 ;
  • Ядро 1 получает ссылку на этот новый объект и читает его в ячейке памяти 0x100 .

В этой ситуации, когда Core 1 запрашивает значение в ячейке 0x100 , возможно ли, что оно считывает устаревшие данные из своих L1 / L2 кеш? Моя интуиция подсказывает, что здесь все еще нужен вентиль памяти, чтобы гарантировать, что ядро ​​1 считывает правильные данные.

Правильно ли приведенный выше анализ и требуется ли вентиль памяти, или я что-то упускаю?

ОБНОВЛЕНИЕ:

Ситуация, которую я описываю здесь, представляет собой более сложную версию того, что происходит каждый раз, когда сборщик мусора выполняет сбор. Когда GC собирает, память переупорядочивается. Это означает, что физическое местоположение объекта изменилось и что L1 / L2 должны быть признаны недействительными. Примерно то же самое относится и к приведенному выше примеру.

Поскольку разумно ожидать, что .NET гарантирует, что после переупорядочения памяти разные ядра увидят правильное состояние памяти, описанная выше ситуация также не будет проблемой.

7
задан Pieter van Ginkel 25 March 2011 в 16:05
поделиться