Если вы хотите, чтобы каждый поток использовал одну и ту же переменную-член, но также поддерживал отдельную копию, у вас есть противоречие. Либо они используют одну и ту же переменную, либо нет. Если я не пойму тебя правильно.
Сказав, что если вам действительно нужно статическое поле для доступа к нескольким потокам, каждый из которых сохраняет свое собственное, личное значение, вы можете использовать атрибут ThreadStatic
. Этот атрибут гарантирует, что статическое поле будет приватным для каждого потока («поток локальный», как его обычно называют).
[ThreadStatic]
private static bool s_threadHasDoneItsWork;
Обратите внимание, что вы не можете инициализировать локальное статическое поле потоков через статический конструктор или непосредственно в качестве static type field = value
. (Компилятор не будет жаловаться, но это не будет работать должным образом.)
volatile
говорит исполняющий, что поле (статическое или нет) всегда должно быть доступно непосредственно из вашей оперативной памяти, так что вы не» t необходимо использовать блокировки или барьеры памяти для синхронизации потоков и ядер. Это всегда актуально, так сказать, тогда как другие поля все еще могут ждать, пока кеш памяти вашего процессора будет синхронизироваться с вашей основной памятью.
Но это точно предел того, что он делает: только доступ к этому конкретному полю. Как только вы его прочитали, значение снова устарело, поэтому никогда не думайте о том, чтобы делать что-то вроде volatileField ++ (что означает «читать volatileField, добавлять его к только что прочитанному значению, устанавливать volatileField», а не «increment volatileField», вам нужно использовать класс Interlocked
для этого, что намного дороже).
Безопасный способ использования изменчивых полей читает их напрямую, но когда вы их изменяете, используйте механизм блокировки, прежде чем вы их прочитаете или напишите. (Единственное разумное исключение, о котором я могу думать, это булевский флаг, например «Я сейчас сделан».)
Практическое использование летучих полей, не удивительно, весьма ограничено. Stick с простой блокировкой; ключевое слово lock
и соответствующие методы класса Monitor
заботятся о единственном пользователе и синхронизации памяти (как только вы входите и выходите из замка).
Да, я видел атрибут Threadstatic на MSDN, и это меня сбило с толку. Кажется, это противоречит определению статической переменной, если каждый поток поддерживает свою личную копию. – Setheron
Это делается в некотором смысле, да. Но это может быть полезно, если вам нужно поддерживать состояние, зависящее от потока, или указать, что методы, вызываемые из одного из ваших методов, должны иметь доступ, но не один. В зависимости от его использования, локальное хранилище потоков может предотвратить необходимость синхронизации потоков (так как нет обмена между потоками), поэтому это может быть полезно. – Ruben
даже не имеет смысла, почему тогда потребуется статическое поле. Только Threadstatic должен иметь смысл. – Setheron