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.

Original source

Related problems