Threadstatic懒惰

时间:2015-12-25 14:37:51

标签: c# multithreading

我很好奇以下示例代码是否是线程安全的:

public class Test
{
    [ThreadStatic]
    private static Foo current;

    public static Foo GetFoo()
    {
        return current ?? (current = new Foo());
    }
}

public class Foo
{
}

通常情况下,我会使用Lazy<T>,但由于每个线程都有一个单独的变量,因此该属性本身应该是线程安全的,这是正确的吗?

感谢。

2 个答案:

答案 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正确初始化。