Подтвердить что ты не робот

Что делает члены экземпляра thread-unsafe vs public static?

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

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

Мой вопрос: что это за переменная экземпляра vs public static делает ее небезопасной?

4b9b3361

Ответ 1

Это справедливо только в целом.

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

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

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

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

Ответ 2

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

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

Это не так, например, методы:

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

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

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

Подробнее

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

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

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

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

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

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

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