ThreadLocal vs local variable in Runnable
java, multithreading, thread-local
Solution
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
...
}
}
Problem
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.