每种方法都需要一个单独的线程锁吗?
Do i need a separate thread lock for each method?
下面是一个创建将由多个线程访问的并发哈希集对象的示例。 'Add' 和 'Remove' 方法都通过锁定对象 _threadLock 锁定。我是否需要为每个方法使用单独的 _threadLock,或者我可以像下面那样共享它吗?
public class ConcurrentHashset<T>
{
private readonly HashSet<T> _hash = new HashSet<T>();
private readonly object _threadLock = new object();
public bool Add(T itemToAdd)
{
lock (_threadLock)
{
return _hash.Add(itemToAdd);
}
}
public bool Remove(T item)
{
lock (_threadLock)
{
return _hash.Remove(item);
}
}
public bool Contains(T item)
{
return _hash.Contains(item);
}
}
这两个操作应该共享同一个锁。
否则,可能会交替调用 Add
和另一个 Remove
,这可能会导致哈希集损坏。
此外,即使 Contains
只读取哈希集但不写入它,它也需要在锁内这样做 - 否则它可能会冒读取当前正在写入的哈希集的风险Add
/Remove
因此处于不一致状态。
(另外,并发 HashSet<T>
的一个更简单的实现是为 ConcurrentDictionary<T, TValue>
提供一个简单的包装器,我们只是忽略这些值。注意 ConcurrentDictionary
是锁定的免费。)
当然锁必须是共享的,否则一开始就没有锁。
如果您正在访问一个项目以进行读取并同时访问它以进行删除,那么事情将不会顺利进行。
下面是一个创建将由多个线程访问的并发哈希集对象的示例。 'Add' 和 'Remove' 方法都通过锁定对象 _threadLock 锁定。我是否需要为每个方法使用单独的 _threadLock,或者我可以像下面那样共享它吗?
public class ConcurrentHashset<T>
{
private readonly HashSet<T> _hash = new HashSet<T>();
private readonly object _threadLock = new object();
public bool Add(T itemToAdd)
{
lock (_threadLock)
{
return _hash.Add(itemToAdd);
}
}
public bool Remove(T item)
{
lock (_threadLock)
{
return _hash.Remove(item);
}
}
public bool Contains(T item)
{
return _hash.Contains(item);
}
}
这两个操作应该共享同一个锁。
否则,可能会交替调用 Add
和另一个 Remove
,这可能会导致哈希集损坏。
此外,即使 Contains
只读取哈希集但不写入它,它也需要在锁内这样做 - 否则它可能会冒读取当前正在写入的哈希集的风险Add
/Remove
因此处于不一致状态。
(另外,并发 HashSet<T>
的一个更简单的实现是为 ConcurrentDictionary<T, TValue>
提供一个简单的包装器,我们只是忽略这些值。注意 ConcurrentDictionary
是锁定的免费。)
当然锁必须是共享的,否则一开始就没有锁。
如果您正在访问一个项目以进行读取并同时访问它以进行删除,那么事情将不会顺利进行。