Мне нужно сделать критический раздел в области на основе конечного набора строк. Я хочу, чтобы блокировка была разделена для одного и того же экземпляра строки (несколько похожа на подход String.Intern).
Я рассматриваю следующую реализацию:
public class Foo
{
private readonly string _s;
private static readonly HashSet<string> _locks = new HashSet<string>();
public Foo(string s)
{
_s = s;
_locks.Add(s);
}
public void LockMethod()
{
lock(_locks.Single(l => l == _s))
{
...
}
}
}
Есть ли проблемы с этим подходом? Хорошо ли блокировать строковый объект таким образом, и есть ли проблемы с безопасностью потоков при использовании HashSet<string>
?
Лучше ли, например, создать Dictionary<string, object>
, который создает новый объект блокировки для каждого экземпляра строки?
Окончательная реализация
Основываясь на предложениях, я пошел со следующей реализацией:
public class Foo
{
private readonly string _s;
private static readonly ConcurrentDictionary<string, object> _locks = new ConcurrentDictionary<string, object>();
public Foo(string s)
{
_s = s;
}
public void LockMethod()
{
lock(_locks.GetOrAdd(_s, s => new object()))
{
...
}
}
}