ThreadStatic vs ThreadLocal<T>

Yan Cui

I help clients go faster for less using serverless technologies.

Occasionally you might want to make the value of a static or instance field local to a thread (i.e. each thread holds an independent copy of the field), what you need in this case, is a thread-local storage.

In C#, there are mainly two ways to do this.

ThreadStatic

You can mark a field with the ThreadStatic attribute:

<br />
[ThreadStatic]<br />
public static int _x;<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_x++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 0 ten times<br />

Whilst this is the easiest way to implement thread-local storage in C# it’s important to understand the limitations here:

  • the ThreadStatic attribute doesn’t work with instance fields, it compiles and runs but does nothing..

<br />
[ThreadStatic]<br />
public int _x;<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_x++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 0, 1, 2, … 9<br />
  • field always start with the default value

<br />
[ThreadStatic]<br />
public static int _x = 1;<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_x++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 0 ten times<br />

ThreadLocal<T>

C#  4 has introduced a new class specifically for the thread-local storage of data – the ThreadLocal<T> class:

<br />
private readonly ThreadLocal&lt;int&gt; _localX = new ThreadLocal&lt;int&gt;(() =&gt; 1);<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_localX++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 1 ten times<br />

There are some bonuses to using the ThreadLocal<T> class:

  • values are lazily evaluated, the factory function evaluates on the first call for each thread
  • you have more control over the initialization of the field and is able to initialize the field with a non-default value

Summary

As you can see, using ThreadLocal<T> has some clear advantages over ThreadStatic, though using 4.0 only features like ThreadLocal<T> means you have to target your project at the .Net 4 framework and is therefore not backward compatible with previous versions of the framework.

It’s also worth noting that besides ThreadLocal<T> and ThreadStatic you can also use Thread.GetData and Thread.SetData to fetch and store thread specific data from and to a named LocalDataStoreSlot though this is usually cumbersome…


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


6 thoughts on “ThreadStatic vs ThreadLocal<T>”

  1. Thank you for your clear explanation.
    One question about 4th block of code. Shouldn’t be _localX.Value++ there?
    With your code compiler says Operator ‘++’ cannot be applied to operand of type ‘System.Threading.ThreadLocal”

    Best regards,
    Grzegorz

  2. Hi,
    What’s with the ‘readonly’ on the
    ‘private readonly ThreadLocal _localX = new ThreadLocal(() => 1);’

Leave a Comment

Your email address will not be published. Required fields are marked *