我需要在一个区域中的关键部分的有限集合串的基础上。我想是相同的字符串实例,(有点类似于共享锁String.Intern方法)。
我正在考虑以下实现:
公共类Foo
{
私人只读字符串_s;
私人静态只读的HashSet<字符串> _locks =新的HashSet<字符串>();
公共美孚(字符串s)
{
_s =秒;
_locks.Add(多个);
}
公共无效LockMethod()
{
锁定(_locks.Single(L =→1 == _s))
{
...
}
}
}
有没有这种做法的任何问题?它是确定一个字符串对象以这种方式锁定,以及是否有使用任何线程安全问题的HashSet<字符串>
是更好,例如,创建一个词典<字符串,对象>
,对于每个字符串实例创建一个新的锁定对象
最终实施
:基于我去下面的实施意见
公共类Foo
{
私人只读字符串_s;
私人静态只读ConcurrentDictionary<字符串,对象> _locks =新ConcurrentDictionary<字符串,对象>();
公共美孚(字符串s)
{
_s =秒;
}
公共无效LockMethod()
{
锁(_locks.GetOrAdd(_s,新的对象()))
{
...
}
}
}
解决方案
锁定琴弦上不鼓励,最主要的原因是(通过实习)一些其他的code可能没有你知道这个锁定相同的字符串。创建死锁情况的可能性。
现在这可能是一个遥不可及的情况下,在大多数具体情况。它多用于图书馆的一般规则。
但是,另一方面,什么是串的感觉到的利益?
所以,点一点:
有没有这种做法的任何问题?
是的,但主要是理论上的。
是否确定一个字符串对象以这种方式锁定,以及是否有在使用HashSet的任何线程安全问题?
在的HashSet<>
不涉及线程安全的,只要线程唯一同时读取
它是更好,例如,创建一个为每个字符串实例创建一个新的锁定对象字典?
是的。只要是在安全方面。在一个大的系统的主要目的是为了避免死锁是保持锁止对象作为本地和私人越好。只有有限的code量应该能够访问它们。
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).
I am considering the following implementation:
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))
{
...
}
}
}
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>
?
Is it better to, for example, create a Dictionary<string, object>
that creates a new lock object for each string instance?
Final Implementation
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 (through interning) some other code could lock on the same string 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?
So, point for point:
Are there any problems with this approach?
Yes, but mostly theoretical.
Is it OK to lock on a string object in this way, and are there any thread safety issues in using the HashSet?
The HashSet<>
is not involved in the thread-safety as long as the threads only read concurrently.
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.