SyncHashtable this [Object key] не использует блокировку - PullRequest
2 голосов
/ 05 июня 2011

Я прошел реализацию SyncHashtable в определенной в .Net Framework BCL.

Этот класс обеспечивает синхронизированный доступ для нескольких читателей и писателей.

Один из методов реализован как

public override Object this[Object key] {
            get {
                    return _table[key];
            }
            set {
                lock(_table.SyncRoot) {
                    _table[key] = value;
                }
            }
        }

По моему мнению, метод get также должен иметь блокировку Syncroot перед доступом к объекту.

Рассмотрим сценарий:

Поток 1: удаление ключей изHashtable.

Поток 2: чтение объектов с использованием ключей.

Если в потоке 2 происходит переключение контекста при чтении объекта и если поток 1 удаляет объект, то в таком случаеОперация чтения потерпит неудачу или выдаст противоречивый результат.

Следовательно, мы не можем реализовать этот метод следующим образом

public override Object this[Object key] {
            get {
                 lock(_table.SyncRoot) 
                  {   
                   return _table[key];
                  }
            }
            set {
                lock(_table.SyncRoot) {
                    _table[key] = value;
                }
            }
        }

Спасибо Vivek

Ответы [ 2 ]

2 голосов
/ 05 июня 2011

Блокировка Hashtable для чтения не обязательна, поскольку в этих обстоятельствах она уже поточно-безопасна.

Документация для Hashtable гласит:

Hashtable является поточно-ориентированным для использования несколькими нитями чтения и одним потоком записи.

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

Обратите внимание, что хотя это верно для Hashtable, не имеет место для Dictionary<TKey, TValue>.

0 голосов
/ 05 июня 2011

Не зная гарантии безопасности потока Hashtable Я считаю, что вы правы, поскольку ключевое слово lock - это монитор, а не неявная блокировка чтения-записи.Это может определенно вызвать нежелательные последствия.Однако, учитывая ситуацию на сегодняшний день, я бы посмотрел на Reactive Extensions для .NET 3.5, он поставляется с сборкой System.Threading, которая содержит новые параллельные классы как часть .NET 4.0.Эти классы намного лучше подходят для работы с многопоточным доступом к коллекциям.

...