Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreadLocal<T> and static approach?

Static fields are being accessed using the class name like this:

public class Me()
{ 
  public static int a=5;
}

I can access it with Me.a, so it is attached to the class.

But when I look at:

static ThreadLocal<int> _x = new ThreadLocal<int> (() => 3);

It guarantees that each thread sees different copy of _x.

Didn't we just see that static is per class and not per thread? How does ThreadLocal manage to give each thread a different copy of _x?

like image 895
Royi Namir Avatar asked Jul 21 '12 11:07

Royi Namir


People also ask

Does ThreadLocal need to be static?

ThreadLocal s should be stored in static variables to avoid memory leaks. If a ThreadLocal is stored in an instance (non-static) variable, there will be M \* N instances of the ThreadLocal value where M is the number of threads, and N is the number of instances of the containing class.

When should I use ThreadLocal?

ThreadLocal is useful, when you want to have some state that should not be shared amongst different threads, but it should be accessible from each thread during its whole lifetime. As an example, imagine a web application, where each request is served by a different thread.

What is ThreadLocal class how and why you should use it?

The ThreadLocal class is used to create thread local variables which can only be read and written by the same thread. For example, if two threads are accessing code having reference to same threadLocal variable then each thread will not see any modification to threadLocal variable done by other thread.

What are ThreadLocal and Threadpool?

ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or transaction ID). The use of ThreadLocal objects requires care in classes whose objects are required to be executed by multiple threads in a thread pool.


2 Answers

The reference _x will indeed be one per class, as per its static specifier. However, only the reference will be shared among all threads, not the value inside its object. When you access _x.Value, ThreadLocal<T> invokes system-specific code that provides storage on the current thread, and reads or writes to that thread-specific storage.

like image 183
Sergey Kalinichenko Avatar answered Oct 03 '22 09:10

Sergey Kalinichenko


My C# isn't that great, so here's a C++ answer to the same effect: Imagine a hypothetical class that contains a large array:

class Foo
{
    int array[HUGE];
    int & get() { return array[this_thread_id()]; }
}:

Now you can have one single, global (or class-static) object:

Foo tlstorage;

To access it from anywhere you say tlstorage.get() = 12;. However, the data is stored in the slot that "belongs" to your current thread. The entire storage is global, but only one slice is exposed to each thread.

Other languages like C and C++ have native support for this concept, and when you decorate a global or static variable as "thread-local", the compiler builds something that amounts to the same effect automatically. Perhaps in C# this is a library feature, though it probably also maps to something intrinsic.

like image 38
Kerrek SB Avatar answered Oct 03 '22 09:10

Kerrek SB