Quick Refresh : Java : ThreadLocal and InheritableThreadLocal
Quick Refresh : Java : ThreadLocal and InheritableThreadLoc al
java.lang.ThreadLocal
This class provides a thread-local variable. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable.
- Basically, it is another way to achieve thread-safety apart from writing immutable classes.
- Since Object is no more shared there is no requirement of Synchronization which can improve scalability and performance of an application.
- It extends Object class.
- ThreadLocal provides thread restriction which is an extension of the local variable. ThreadLocal is visible only in a single thread. No two threads can see each other's thread-local variables.
- These variables are generally private static fields in classes and maintain their state inside a thread.
Creating a ThreadLocal
Here is a code example that shows how to create a ThreadLocal
variable:
private ThreadLocal myThreadLocal = new ThreadLocal();
As you can see, you instantiate a new ThreadLocal
object. This only needs to be done once per thread. Even if different threads execute the same code which accesses a ThreadLocal
, each thread will see only its own ThreadLocal
instance. Even if two different threads set different values on the sameThreadLocal
object, they cannot see each other's values.
ThreadLocal
variable:private ThreadLocal myThreadLocal = new ThreadLocal();As you can see, you instantiate a new
ThreadLocal
object. This only needs to be done once per thread. Even if different threads execute the same code which accesses a ThreadLocal
, each thread will see only its own ThreadLocal
instance. Even if two different threads set different values on the sameThreadLocal
object, they cannot see each other's values.Accessing a ThreadLocal
Once a ThreadLocal
has been created you can set the value to be stored in it like this:
myThreadLocal.set("A thread local value");
You read the value stored in a ThreadLocal
like this:
String threadLocalValue = (String) myThreadLocal.get();
The get()
method returns an Object
and the set()
method takes an Object
as parameter.
ThreadLocal
has been created you can set the value to be stored in it like this:myThreadLocal.set("A thread local value");You read the value stored in a
ThreadLocal
like this:String threadLocalValue = (String) myThreadLocal.get();The
get()
method returns an Object
and the set()
method takes an Object
as parameter.Generic ThreadLocal
You can create a generic ThreadLocal
so that you do not have to typecast the value returned by get()
. Here is a generic ThreadLocal
example:
private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();
Now you can only store strings in the ThreadLocal
instance. Additionally, you do not need to typecast the value obtained from the ThreadLocal
:
myThreadLocal.set("Hello ThreadLocal");
String threadLocalValue = myThreadLocal.get();
ThreadLocal
so that you do not have to typecast the value returned by get()
. Here is a generic ThreadLocal
example:private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();Now you can only store strings in the
ThreadLocal
instance. Additionally, you do not need to typecast the value obtained from the ThreadLocal
:myThreadLocal.set("Hello ThreadLocal"); String threadLocalValue = myThreadLocal.get();
Initial ThreadLocal Value
Since values set on a ThreadLocal
object only are visible to the thread who set the value, no thread can set an initial value on a ThreadLocal
using set()
which is visible to all threads.
Instead you can specify an initial value for a ThreadLocal
object by subclassing ThreadLocal
and overriding the initialValue()
method. Here is how that looks:
private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
@Override protected String initialValue() {
return "This is the initial value";
}
};
Now all threads will see the same initial value when calling get()
before having called set()
.
ThreadLocal
object only are visible to the thread who set the value, no thread can set an initial value on a ThreadLocal
using set()
Instead you can specify an initial value for a
ThreadLocal
object by subclassing ThreadLocal
and overriding the initialValue()
method. Here is how that looks:private ThreadLocal myThreadLocal = new ThreadLocal<String>() { @Override protected String initialValue() { return "This is the initial value"; } };Now all threads will see the same initial value when calling
get()
before having called set()
.Full ThreadLocal Example
Here is a fully runnable Java ThreadLocal
example:
public class ThreadLocalExample {
public static class MyRunnable implements Runnable {
private ThreadLocal<Integer> threadLocal =
new ThreadLocal<Integer>();
@Override
public void run() {
threadLocal.set( (int) (Math.random() * 100D) );
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println( threadLocal.get());
}
}
public static void main(String[] args) {
MyRunnable sharedRunnableInstance = new MyRunnable();
Thread thread1 = new Thread(sharedRunnableInstance) ;
Thread thread2 = new Thread(sharedRunnableInstance) ;
thread1.start();
thread2.start();
thread1.join(); //wait for thread 1 to terminate
thread2.join(); //wait for thread 2 to terminate
}
}
This example creates a single MyRunnable
instance which is passed to two different threads. Both threads execute the run()
method, and thus sets different values on the ThreadLocal
instance. If the access to theset()
call had been synchronized, and it had not been a ThreadLocal
object, the second thread would have overridden the value set by the first thread.
However, since it is a ThreadLocal
object then the two threads cannot see each other's values. Thus, they set and get different values.
ThreadLocal
example:public class ThreadLocalExample { public static class MyRunnable implements Runnable { private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); @Override public void run() { threadLocal.set( (int) (Math.random() * 100D) ); try { Thread.sleep(2000); } catch (InterruptedException e) { } System.out.println(This example creates a singlethreadLocal.get()); } } public static void main(String[] args) { MyRunnable sharedRunnableInstance = new MyRunnable(); Thread thread1 = new Thread(sharedRunnableInstance) ; Thread thread2 = new Thread(sharedRunnableInstance) ; thread1.start(); thread2.start(); thread1.join(); //wait for thread 1 to terminate thread2.join(); //wait for thread 2 to terminate } }
MyRunnable
instance which is passed to two different threads. Both threads execute the run()
method, and thus sets different values on the ThreadLocal
instance. If the access to theset()
call had been synchronized, and it had not been a ThreadLocal
object, the second thread would have overridden the value set by the first thread.However, since it is a
ThreadLocal
object then the two threads cannot see each other's values. Thus, they set and get different values.
java.lang. InheritableThreadLocal
The InheritableThreadLocal
class is a subclass of ThreadLocal
. Instead of each thread having its own value inside a ThreadLocal
, the InheritableThreadLocal
grants access to values to a thread and all child threads created by that thread.
InheritableThreadLocal contain s only one method. By default, child thread value is exactly the same as parent thread value. But we can provide our own customized value for child thread by overriding childValue method.
public Object childValue(Object parentValue)
Note: ThreadLocal variable by default is not available to child thread
The class is a subclass of grants access to values to a thread and all child threads created by that thread.
InheritableThreadLocal containInheritableThreadLocal
ThreadLocal
. Instead of each thread having its own value inside a ThreadLocal
, the InheritableThreadLocal
public Object childValue(Object parentValue)
Note: ThreadLocal variable by default is not available to child thread
Comments
Post a Comment