2012-01-17 2 views
0

Можно создать дубликат:
Is using an existing object rather than creating a specific lock object safe?замок на частном статическом поле, которое используется

Что вы думаете: это хорошая практика, чтобы зафиксировать на частных статических объектов, которые используются внутри мои занятия? Например, у меня есть словарь, который содержит элементы, и при его изменении я блокирую (myList). Я предпочитаю использовать специальное частное поле System.Object, которое используется как блокировка, но мой коллега полагает, что нормально использовать личное статическое поле, потому что оно уже закрыто.

ответ

3

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

Если вы блокируете, чтобы безопасно работать со словарем или списком, рассмотрели ли вы использование объектов System.Generic.Collections.Concurrent?

Кроме того, вы считали ReaderWriterLock? Таким образом, вы можете разрешить несколько чтений, но безопасно заблокировать, чтобы разрешить только одну запись за раз.

Подробнее

Там нет никакой разницы блокировки против отдельного объекта против блокировки на самом словаре. CLR создает или назначает структуру SyncBlock и управляет счетчиком блокировки без учета блокируемого объекта. Более подробная информация о том, что здесь: http://msdn.microsoft.com/en-us/magazine/cc188793.aspx

То, что я думаю:

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

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

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

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

В CLR есть объекты, предназначенные специально для синхронизации потоков. SyncLock и Monitor.Enter хороши в большинстве случаев, но вы можете получить гораздо лучшую производительность, переключившись на ReaderWriterLock. Мало того, что вы можете одновременно пропускать несколько потоков, но вы можете безопасно заблокировать весь поток, чтобы разрешить синхронную запись. Краткое описание здесь: http://www.codekicks.com/2008/03/readerwriterlock-cnet-systemthreading.html

+0

Благодарим вас за ответ, но мой вопрос не в том, что касается списка, но это, если это сохранить, чтобы заблокировать частный статический объект, который используется классом. –

+0

А, я вижу.Я обновил свой ответ с дополнительной информацией. В принципе, это безопасно, если вы полностью осознаете, когда и что заблокировано; но наличие отдельного объекта только для блокировки намного безопаснее, потому что его намерение очевидно. –

Смежные вопросы