.NET: обновляет безопасный параллелизм переменной ссылочного типа? [Дубликат]

В зависимости от использования вы можете использовать метод для печати определенной строки. Что-то вроде этого

public void printRow(int r){
    for(int i=0; i<table[r-1].length; i++){
        if(i>0){
            System.out.print(", ");
        }
        System.out.print(table[r-1][i]);
    }
}

В этом примере вы должны называть printRow(2);, когда хотите распечатать вторую строку.

32
задан Justin Johnson 6 March 2011 в 10:17
поделиться

2 ответа

Да, обновления ссылок гарантированно будут атомарными в спецификации языка.

5.5 Атомарность ссылок на переменные

Считывание и запись следующих типов данных являются атомарными: bool, char, byte, sbyte, short, ushort, uint, int, float и reference. Кроме того, чтение и запись типов перечислений с базовым типом в предыдущем списке также являются атомарными. Чтения и записи других типов, включая длинные, улоновые, двойные и десятичные, а также определяемые пользователем типы, не гарантируются как атомарные.

Однако внутри жесткой петли вы можете укусить кеширование регистра. Вряд ли в этом случае, если ваш метод-вызов не вставлен (что может случиться). Лично я бы добавил lock, чтобы сделать его простым и предсказуемым, но volatile тоже может помочь. Обратите внимание, что полная безопасность потоков - это больше, чем просто атомарность.

В случае кеша я бы посмотрел на Interlocked.CompareExchange, лично - т.е. попробовал для обновления , но если он не выполнит повторную работу с нуля (начиная с нового значения) и повторите попытку.

54
ответ дан Marc Gravell 18 August 2018 в 15:44
поделиться
  • 1
    +1 Отлично, спасибо за быстрый ответ. У вас не было бы ссылки на спецификацию языка. Если он доступен онлайн? – Steffen 6 March 2011 в 10:10
  • 2
    @Steffan просто ищет «Спецификация языка C #», которая, как правило, легко находит версии MS. Или ECMA334 для общедоступной версии 2.0. – Marc Gravell♦ 6 March 2011 в 10:13
  • 3
    +1 Для выработки сверх простоты. – Albin Sunnanbo 6 March 2011 в 10:22
  • 4
    Может кто-то уточнить, что «вы можете укусить кеширование регистра»? Каковы будут последствия этого? – Nathan 30 August 2015 в 02:57
  • 5
    @Nathan просто: поток A не обязательно видит изменения, которые поток B делает для переменной. Это особенно заметно с такими вещами, как bool shouldRun = true;, while(shouldRun) {...} и второй поток, который устанавливает shouldRun = false; – Marc Gravell♦ 30 August 2015 в 08:43

В ответе @Marc Gravell, как указано в C # Language Spec 5.5, важно знать, что понимается под термином «определяемый пользователем тип». Я не нашел четкого определения w.r.t. это использование в языке C # Spec. В UML и в общем выражении класс является экземпляром типа. Но в контексте C # Language Spec это значение неясно.

Справочник по языку Visual Basic «Определенные пользователем типы» (в https://msdn.microsoft.com/en- us / library / cec05s9z.aspx ) говорит

«Предыдущие версии Visual Basic поддерживают пользовательский тип (UDT). Текущая версия расширяет UDT до структуры».

, поэтому кажется, что пользовательский тип является структурой, а не классом.

Но ....

В соответствии с «Руководством по программированию на C #» «Типы» (в https://msdn.microsoft.com/en-us/ library / ms173104.aspx ):

«Типичная программа C # использует типы из библиотеки классов, а также пользовательские типы»

, который подразумевает, что класс является определяемым пользователем типом. Позднее он приводит пример «сложных пользовательских типов:»

MyClass myClass;

, что означает, что «MyClass» - это пользовательский тип , И позже он говорит:

«Каждый тип в CTS определяется как тип значения или ссылочный тип, включая все пользовательские типы в библиотеке классов .NET Framework и ваши собственные пользовательские типы . "

... что подразумевает, что все классы, созданные разработчиком, являются« Пользовательским типом ».

И, наконец, есть этот элемент Stackoverflow, в котором значение этого термина обсуждается неубедительно: Как определить, является ли свойство определяемым пользователем типом в C #?

Поэтому, чтобы быть в безопасности, я вынужден рассматривать все классы, созданные мной или те, которые содержатся в .Net Framework, все должны быть определенными пользователем типами, и поэтому Not Thread Safe для назначения , потому что он говорит в разделе 5.5 языка C #:

Чтения и записи ... а также определяемые пользователем типы не гарантируются как атомарные.

К сожалению, разговорный термин используется в точной спецификации, такой как C # Language Specification. Из-за этой двусмысленности, чтобы быть потокобезопасным, я могу писать менее оптимальный код, чем это было бы возможно, если окажется, что «Пользовательский тип» не включает классы CLR.

Поэтому Я прошу о дальнейших разъяснениях этого ответа stackoverflow, поскольку его текущая основа ответа оставляет эту значительную двусмысленность. В его нынешнем виде ответ на вопрос «Является ли ссылочным назначением потокобезопасным?» кажется «НЕТ».

0
ответ дан Community 18 August 2018 в 15:44
поделиться
  • 1
    Несмотря на кажущуюся несогласованность в использовании термина «определяемые пользователем типы», я не думаю, что это ставит под вопрос исходный ответ. Выделение соответствующих частей: «Чтение и запись следующих типов данных - это атомарные: bool, char, ... и ссылочные типы. Чтения и записи ДРУГИХ ТИПОВ, включая ... определяемые пользователем типы, не гарантируются как атомарные. & Quot; По-моему, "другие" в этом случае явно исключает все, что включено в первоначальный список (например, типы ссылок). Таким образом, даже если «пользовательские типы» иногда можно использовать для описания классов, этого, конечно, нет. – The Mad Coder 18 May 2015 в 04:03
Другие вопросы по тегам:

Похожие вопросы: