Что делает члены экземпляра потокобезопасными против общедоступных статических - PullRequest
19 голосов
/ 09 августа 2009

Итак, мы все видели уведомление о потоке на MSDN для многих доступных универсальных объектов:

"Публичные статические (совместно используемые в Visual Basic) члены этого типа являются поточно-ориентированными. Любые члены экземпляра не гарантируют поточно-ориентированные."

У меня вопрос: что из-за того, что переменная экземпляра против общедоступной статики делает ее небезопасной?

Ответы [ 5 ]

15 голосов
/ 09 августа 2009

Это верно только в общем.

В общем случае статические методы являются статическими, поскольку они не зависят и не обращаются к каким-либо данным, определенным экземпляром, к которым другой поток также может получить доступ. В общем, единственные переменные, которые они (статический метод) используют, - это переменные, объявленные и привязанные к статической памяти класса, в котором реализован метод, а не к памяти, выделенной для объекта - (экземпляра класса), созданного для этого объекта , Статический метод не имеет и не может ссылаться или использовать любую такую ​​переменную. Если метод использует этот тип переменной данных экземпляра, привязанный к конкретному экземпляру, он не может быть статическим. Метод Instance, напротив, осуществляет доступ к некоторому элементу данных (свойству или полю) экземпляра.

Если, кроме того, статический метод обращается к статическому свойству или полю класса, он в равной степени не является потокобезопасным.

Для гонки возможны четыре условия.

  1. Первым условием является наличие областей памяти, доступных из нескольких потоков. Как правило, эти местоположения являются глобальными / статическими переменными или могут быть доступны из динамической памяти из глобальных / статических переменных.
  2. Вторым условием является наличие свойства (часто называемого инвариантом), которое связано с этими местами общей памяти, которые должны быть истинными или действительными, чтобы программа функционировала правильно. Как правило, свойство должно иметь значение true, прежде чем произойдет обновление, чтобы обновление было корректным.
  3. Третье условие заключается в том, что свойство инварианта не выполняется во время какой-либо части фактического обновления. (Это временно недействительно или ложно во время некоторой части обработки).
  4. Четвертое и последнее условие, которое должно произойти для гонки, состоит в том, что другой поток обращается к памяти, пока инвариант нарушается, вызывая, таким образом, непоследовательное или неправильное поведение.
13 голосов
/ 09 августа 2009

Ничего встроенный делает статическое более или менее отличным (в отношении безопасности потоков) от экземпляра, за исключением:

  • статические методы часто являются "чисто функциональными" методами без сохранения состояния, что делает их автоматически поточно-безопасными
  • существует явное ожидание для статических элементов быть потоко-безопасным (поскольку вы не можете реально контролировать, что каждый поток делает одновременно) - так что ожидается , что любой статический метод, который может сделать риск поточной безопасности потокобезопасным

Это не так для методов экземпляра:

  • методы экземпляра обычно обращаются к состоянию в этом экземпляре
  • ожидание безопасности потока не ожидается, если это не указано явным образом в документации

Таким образом, в общем случае ожидается, что вызывающий управляет безопасностью потоков по экземплярам.

Существуют исключения, когда экземпляры являются поточно-ориентированными (обычно для вещей, которые тесно связаны с многопоточностью, таких как очередь «производитель-получатель»), но любой статический член IMO, который не является поточно-ориентированным, является ошибкой.

8 голосов
/ 09 августа 2009

Это вопрос государства. Что в целом делает методы небезопасными для нескольких потоков, так это то, что они не обращаются к общему состоянию потокобезопасным способом. Статические методы в целом не имеют доступа к общему состоянию и, следовательно, с меньшей вероятностью столкнутся с этой проблемой. Все еще возможно иметь условия гонки в статических / общих методах, если они касаются статических данных, но в общем случае статических методов нет.

0 голосов
/ 03 июня 2017

TLDR; «Означает ли это, что статические методы по своей природе являются поточно-ориентированными? Ответ - нет. Классы с указанным выше примечанием будут иметь поточно-ориентированные статические методы, потому что инженеры Microsoft написали код поточно-ориентированным способом, возможно, с помощью блокировок или других механизмов синхронизации потоков». (цитата взята из http://odetocode.com/Articles/314.aspx)

Подробнее

Что это? Ничего, кроме кода, написанного для этого конкретного класса.

Это заявление является декларацией о том, что программисты, написавшие класс, позаботились о том, чтобы все статические члены (методы и свойства) были поточно-ориентированными (но не сделали этого для членов экземпляра).

Они убедились, что статические потоки безопасны, потому что, будучи статичными, очень вероятно, что они будут вызываться несколькими потоками, поэтому они вносят дополнительную работу, необходимую, чтобы убедиться, что все будет в порядке. Часто статические методы также являются функциями без сохранения состояния, то есть они, как правило, уже поточно-ориентированы (дополнительная работа не требуется).

Напротив, например, члены утверждают, что они просто говорят вам, что они не так осторожны с ними.

Часто экземпляры создаются одним потоком и доступны только этому потоку; если к экземпляру никогда не обращаются из нескольких потоков, то безопасность потоков не является проблемой, поэтому программисты не удосужились добавить его.

Заявление не является утверждением о каких-либо внутренних свойствах static vs instance; и то, и другое может быть небезопасным, если вы не добавите конкретный код, чтобы гарантировать, что несколько потоков смогут без проблем получить к ним доступ (или если по своей природе они уже поточно-ориентированы, например, функция без сохранения состояния).

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

0 голосов
/ 09 августа 2009

Проблема с методами, которые не являются потокобезопасными, заключается в параллельном доступе к общим ресурсам, таким как переменные экземпляра.Если статический метод only работает с частными / локальными данными, он по сути является поточно-ориентированным.Тем не менее, нет никакой гарантии, что статические методы делают это - это должно быть сделано явно.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...