Which one among ThreadLocal
or a local variable in Runnable
will be preferred? For performance reasons. I hope using a local variable will give more chances for cpu caching, etc.
-
If you're interested purely in performance of ThreadLocal vs. local variables, this question has a lot of good reading: http://stackoverflow.com/questions/609826/performance-of-threadlocal-variable – Alex Apr 12 '12 at 00:29
4 Answers
Which one among ThreadLocal or a local variable in Runnable will be preferred.
If you have a variable that is declared inside the thread's class (or the Runnable
) then a local variable will work and you don't need the ThreadLocal
.
new Thread(new Runnable() {
// no need to make this a thread local because each thread already
// has their own copy of it
private SimpleDateFormat format = new SimpleDateFormat(...);
public void run() {
...
// this is allocated per thread so no thread-local
format.parse(...);
...
}
}).start();
On the other hand, ThreadLocal
s are used to save state on a per thread basis when you are executing common code. For example, the SimpleDateFormat
is (unfortunately) not thread-safe so if you want to use it in code executed by multiple threads you would need to store one in a ThreadLocal
so that each thread gets it's own version of the format.
private final ThreadLocal<SimpleDateFormat> localFormat =
new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(...);
}
};
...
// if a number of threads run this common code
SimpleDateFormat format = localFormat.get();
// now we are using the per-thread format (but we should be using Joda Time :-)
format.parse(...);
An example of when this is necessary is a web request handler. The threads are allocated up in Jetty land (for example) in some sort of pool that is outside of our control. A web request comes in which matches your path so Jetty calls your handler. You need to have a SimpleDateFormat
object but because of its limitations, you have to create one per thread. That's when you need a ThreadLocal
. When you are writing reentrant code that may be called by multiple threads and you want to store something per-thread.
Instead, if you want pass in arguments to your Runnable
then you should create your own class and then you can access the constructor and pass in arguments.
new Thread(new MyRunnable("some important string")).start();
...
private static class MyRunnable implements {
private final String someImportantString;
public MyRunnable(String someImportantString) {
this.someImportantString = someImportantString;
}
// run by the thread
public void run() {
// use the someImportantString string here
...
}
}

- 115,027
- 24
- 293
- 354
-
Nice, but I would change the ThreadLocal example to initialize localFormat with an anonymous subclass that overrides initialValue, since that's the typical usage pattern. – Alex Apr 12 '12 at 00:24
-
you misunderstand me. Look at the example code in the Javadoc for ThreadLocal - it shows how to properly put the initialization code for the per-thread variable into a common place so that it's initialized for each calling thread before being returned by get(), no matter where it's called from. – Alex Apr 12 '12 at 00:33
-
-
'Certainly you could pass in your format as an argument to the common code block but then you wouldn't need the ThreadLocal' - sounds like ThreadLocal storage is redundant, then. It sounds to me like TLS is space to declare global variables for the thread, but without actually calling them globals so that all the arguments against the use of global variables cannot be applied
Go on, someone tell me that a thread with TLS is different than a single-threaded program with lots of global variables... – Martin James Apr 12 '12 at 00:52 -
I'd agree with that @Martin. `ThreadLocal`s are even more expensive than globals but they are certainly much better scoped. I use `ThreadLocal` in situations like I mention at the end of my answer when there is a requirement. Splattering code with them does not improve a bad object design that requires tons of globals for sure. Cheers. – Gray Apr 12 '12 at 00:55
Whenever your program could correctly use either of the two (ThreadLocal
or local variable), choose the local variable: it will be more performant.
ThreadLocal
is for storing per-thread state past the execution scope of a method. Obviously local variables can't persist past the scope of their declaration. If you needed them to, that's when you might start using a ThreadLocal
.
Another option is using synchronized
to manage access to a shared member variable. This is a complicated topic and I won't bother to go into it here as it's been explained and documented by more articulate people than me in other places. Obviously this is not a variant of "local" storage -- you'd be sharing access to a single resource in a thread-safe way.

- 10,027
- 3
- 40
- 54
-
1I've never understood ThreadLocal storage. I have been writing multithreaded apps for 30 years and have never used TLS. When a thread is started, the CreateThread(), or whatever, call takes the address whenre the thread should execute. In most languages, this is a procedure/function and a local stack variable declared there will have the lifetime of the thread. In OO languages, there is usually an extra parameter in the create call that can transfer 'this' and so a thread can have instance data members as well. SO, why TLS? What does it give me that's 'special'? – Martin James Apr 12 '12 at 00:45
I was also confused why i need ThreadLocal when i can just use local variables, since they both maintain their state inside a thread. But after a lot of searching and experimenting i see why is ThreadLocal needed.
I found two uses so far -
- Saving thread specific values inside the same shared object
- Alternative to passing variables as parameters through N-layers of code
1:
If you have two threads operating on the same object and both threads modify this object - then both threads keep losing their modifications to each other.
To make this object have two separate states for each thread, we declare this object or part of it ThreadLocal.
Of course, ThreadLocal is only beneficial here because both threads are sharing the same object. If they are using different objects, there's no need for the objects to be ThreadLocal.
2:
The second benefit of ThreadLocal, seems to be a side effect of how its implemented.
A ThreadLocal variable can be .set() by a thread, and then be .get() anywhere else. .get() will retrieve the same value that this thread had set anywhere else. We'll need a globally available wrapper to do a .get() and .set(), to actually write down the code.
When we do a threadLocalVar.set() - its as if its put inside some global "map", where this current thread is the key.
As if - someGlobalMap.put(Thread.currentThread(),threadLocalVar);
So ten layers down, when we do threadLocalVar.get() - we get the value that this thread had set ten layers up.
threadLocalVar = someGlobalMap.get(Thread.currentThread());
So the function at tenth level does not have to lug around this variable as parameter, and can access it with a .get() without worrying about if it is from the right thread.
Lastly, since a ThreadLocal variable is a copy to each thread, of course, it does not need synchronization. I misunderstood ThreadLocal earlier as an alternative to synchronization, that it is not. It is just a side effect of it, that we dont need to synchronize the activity of this variable now.
Hope this has helped.

- 315
- 2
- 11
This question is answered by the simple rule that a variable should be declared in the smallest possible enclosing scope. A ThreadLocal
is the largest possible enclosing scope so you should only use it for data that is needed across many lexical scopes. If it can be a local variable, it should be.

- 305,947
- 44
- 307
- 483
-
I think they should be called 'Thread Globals', then no-one would use them. For years I read posts, blogs,articles 'Don't use global variables'. Then, someone decides that threads can have something called 'TLS' - yippee! globals again, but under another name so they stay cool. Is it alright now to write single-threaded programs with lots of global variables, as long as they are stored in the TLS of the main thread? IMHO, this TLS thingy is a silly feature that solves nothing new. – Martin James Apr 12 '12 at 01:00
-
@MartinJames I agree completely. I've used them about twice in 15 years and regretted it every time. – user207421 Apr 12 '12 at 01:06
-
@MartinJames I agree that `ThreadLocal`s should be used sparingly or preferably not at all. – Mike Clark Apr 12 '12 at 16:59