我很好奇以下示例代码是否是线程安全的:
public class Test
{
[ThreadStatic]
private static Foo current;
public static Foo GetFoo()
{
return current ?? (current = new Foo());
}
}
public class Foo
{
}
通常情况下,我会使用Lazy<T>
,但由于每个线程都有一个单独的变量,因此该属性本身应该是线程安全的,这是正确的吗?
感谢。
答案 0 :(得分:5)
您提供的代码看起来非常安全。如果您对Lazy<T>
感到满意,可以使用ThreadLocal<T>
,它以类似的方式工作,但每个线程都保存其值线程安全。
// Thread-Local variable that yields a name for a thread
ThreadLocal<string> ThreadName = new ThreadLocal<string>(() =>
{
return "Thread" + Thread.CurrentThread.ManagedThreadId;
});
https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx
答案 1 :(得分:1)
代码确实是Thread
- 安全但请注意 每个Thread
将拥有自己的实例 ,这意味着例如,在Singleton中,您不应该使用ThreadStaticAttribute
。
我为此属性找到的更有用的用法是,不是Thread
- 安全类Thread
- 安全 - 例如Random
。
Random.Next
调用,则{p> 0
可能会返回Threads
,因此ThreadStatic
会使每个Thread
的实例不同。
另一方面,ThreadStatic
不会自动初始化每个Thread
的字段。
ThreadLocal<T>
允许您提供一个像Lazy<T>
一样使用的初始化方法,并在每个Thread
的第一次访问时为您初始化内容。
请注意,ThreadLocal<T>
会要求您通过其Value
媒体资源访问实际数据。
此外,无论如何,您的初始化都采用GetFoo
方法,因此每个实例也会使用ThreadStatic
正确初始化。