public static HashSet<string> thread safe?
Basically i have an app c开发者_如何学Pythonalling 3 different threads that each that a new HashSet and I want to know is this thread safe? or do I need a [ThreadStatic] added to each hashset?
If you instantiate three different HashSet
s, and each HashSet
is accessed only by a single thread, then it will be fine. You only need to add the [ThreadStatic]
attribute if there is a single static HashSet
shared among threads.
[Update] Just to clarify how [ThreadStatic]
would work.
Disclaimer: I never use [ThreadStatic]
. The presence of that attribute has a lot of consequences which are not obvious and are hard to debug (as well as test properly) IMO.
Let's say you really want to use [ThreadStatic]
in a test class:
public class ThreadStaticTest
{
// CLR ensures that each thread accessing this field
// gets a separate instance of the *field*. This, however,
// means that static initializers don't work. Field is
// null at first access from an individual thread
[ThreadStatic]
static HashSet<string> _hashset;
// This is why we instantiate it explicitly here:
private HashSet<string> HashSet
{
get
{
_hashset = _hashset ?? new HashSet<string>();
return _hashset;
}
}
public void AddItem(string s)
{
// thread safe
HashSet.Add(s);
}
public IEnumerable<string> GetItems()
{
// thread safe
return HashSet;
}
}
Running the following console app:
static void Main(string[] args)
{
// single test instance!
var test = new ThreadStaticTest();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 5; i++)
{
threads.Add(new Thread(() =>
{
var threadId = Thread.CurrentThread.ManagedThreadId;
test.AddItem("Hello from thread #" + threadId);
Console.WriteLine("Instance contains {0} items: '{1}'",
test.GetItems().Count(),
string.Join(", ", test.GetItems().ToArray()));
}));
}
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
Console.Read();
}
Shows that, although there is a single test instance, each thread gets a new instance of the hashset:
Instance contains 1 items: 'Hello from thread #11' Instance contains 1 items: 'Hello from thread #13' Instance contains 1 items: 'Hello from thread #10' Instance contains 1 items: 'Hello from thread #12' Instance contains 1 items: 'Hello from thread #14'
According to the MSDN docs for HashSet
:
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
精彩评论