可以使用字符串作为锁定对象吗? [英] Is it OK to use a string as a lock object?
问题描述
我需要根据有限的字符串集在一个区域中创建一个临界区.我希望为同一个字符串实例共享锁,(有点类似于 String.Intern 方法).
I need to make a critical section in an area on the basis of a finite set of strings. I want the lock to be shared for the same string instance, (somewhat similar to String.Intern approach).
我正在考虑以下实现:
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
是否存在线程安全问题?
Are there any problems with this approach? Is it OK to lock on a string object in this way, and are there any thread safety issues in using the HashSet<string>
?
例如,创建一个 Dictionary
为每个字符串实例创建一个新的锁对象是否更好?
Is it better to, for example, create a Dictionary<string, object>
that creates a new lock object for each string instance?
最终实施
根据建议,我进行了以下实施:
Based on the suggestions I went with the following implementation:
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, _ => new object()))
{
...
}
}
}
推荐答案
不鼓励锁定字符串,主要原因是(因为字符串实习)某些其他代码可能会在您不知道的情况下锁定同一个字符串实例.创造潜在的死锁情况.
Locking on strings is discouraged, the main reason is that (because of string-interning) some other code could lock on the same string instance without you knowing this. Creating a potential for deadlock situations.
现在,在大多数具体情况下,这可能是一个牵强的场景.这更像是图书馆的一般规则.
Now this is probably a far fetched scenario in most concrete situations. It's more a general rule for libraries.
但另一方面,字符串的感知好处是什么?
But on the other hand, what is the perceived benefit of strings?
所以,一点一点:
这种方法有什么问题吗?
Are there any problems with this approach?
是的,但主要是理论性的.
Yes, but mostly theoretical.
以这种方式锁定字符串对象是否可以,使用HashSet是否存在线程安全问题?
Is it OK to lock on a string object in this way, and are there any thread safety issues in using the HashSet?
HashSet<>
不涉及线程安全,只要线程只并发读取即可.
The HashSet<>
is not involved in the thread-safety as long as the threads only read concurrently.
例如,创建一个为每个字符串实例创建一个新锁对象的 Dictionary 是否更好?
Is it better to, for example, create a Dictionary that creates a new lock object for each string instance?
是的.只是为了安全起见.在大型系统中,避免死锁的主要目的是使锁对象尽可能保持本地和私有.只有有限数量的代码才能访问它们.
Yes. Just to be on the safe side. In a large system the main aim for avoiding deadlock is to keep the lock-objects as local and private as possible. Only a limited amount of code should be able to access them.
这篇关于可以使用字符串作为锁定对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!