Java — ThreadLocal | Code Factory
4 min readJun 5, 2020
Index Page : Link
Donate : Link
WordPress Blog : Link
- ThreadLocal class provides thread local variable.
- ThreadLocal class maintains values per thread basis.
- Each ThreadLocal object maintains a seperate value like user id, transaction id, etc… for each thread that accesses that object.
- Thread can access it’s local value, can manipulate it’s value and even can remove it’s value.
- In every part of the code which is executed by the thread we can access it’s local variable.
- Ex. Consider a servlet which invokes some business methods, we have a requirement to generate a unique transaction id for each and every request and we have to pass this transaction id to the business methods for this requirement we can use ThreadLocal to maintain a seperate transaction id for every request that is for every thread.
Note :
- ThreadLocal class introduced in 1.2v and enhanced in 1.5v.
- ThreadLocal can be associated with thread scope.
- Total code which is executed by the thread has access to the corresponding thread local variables.
- A thread can access it’s own local variables and can’t access other thread local variables.
- Once a thread entered into dead state all it’s local variables by default avaialble/eligible for garbage collection (GC) .
Constructor :
1. ThreadLocal tl = new ThreadLocal();
- Creates a thread local variable.
Methods :
1. public T get()
- Returns the value of ThreadLocal variable associated with current thread.
2. protected Object initialValue()
- Returns initial value of ThreadLocal variable associated with current thread.
- The default implementation of this method return null.
- To customize our own initialize value we have tooverride this method.
3. public void set(Object value)
- To set a new value
4. public void remove()
- To remove the value of ThreadLocal variable associated with current thread.
- It is newly added method in 1.5v.
- After removal if we are trying to access it will be reinitialized once again by invoking it’s initialValue() method.
Example 1 :
package com.example.thread;/**
* @author code.factory
*
*/
public class ThreadLocalTest {
public static void main(String... args) {
ThreadLocal tl = new ThreadLocal();
System.out.println(tl.get()); // null
tl.set("Code");
System.out.println(tl.get()); // Code
tl.remove();
System.out.println(tl.get()); // null
}
}
Example 2 :
package com.example.thread;/**
* @author code.factory
*
*/
public class ThreadLocalTest {
public static void main(String... args) {
ThreadLocal tl = new ThreadLocal() {
public Object initialValue() {
return "Hello";
}
};
System.out.println(tl.get()); // Hello
tl.set("Code");
System.out.println(tl.get()); // Code
tl.remove();
System.out.println(tl.get()); // Hello
}
}
Example 3 :
package com.example.thread;/**
* @author code.factory
*
*/
public class ThreadLocalTest {
public static void main(String... args) {
CustomerThread c1 = new CustomerThread("Customer 1");
CustomerThread c2 = new CustomerThread("Customer 2");
CustomerThread c3 = new CustomerThread("Customer 3");
CustomerThread c4 = new CustomerThread("Customer 4");
c1.start();
c2.start();
c3.start();
c4.start();
}
}class CustomerThread extends Thread {
static Integer custId = 0;
private static ThreadLocal tl = new ThreadLocal() {
protected Integer initialValue() {
// synchronized(this) { // #1
return ++custId;
// } // #2
}
};
CustomerThread(String name) {
super(name);
}
public void run() {
System.out.println(Thread.currentThread().getName() + " customer id : " + tl.get());
}
}
Output :
Customer 4 customer id : 3
Customer 2 customer id : 2
Customer 3 customer id : 4
Customer 1 customer id : 1
- In the above program for every customer thread a seperate customer id will be maintained by ThreadLocal object.
- If you didn’t get proper output then uncomment line #1 and #2.
- Parent thread’s ThreadLocal variable by default not available to the child thread.
- If we want to make parent thread’s ThreadLocal variable value available to the child thread then we should go for
InheritableThreadLocal
class. - By default child thread’s value is exactly same as parent thread’s value but we can provide customized value for child thread by overriding childValue() method.
Constructors :
1. InheritableThreadLocal t = new InheritableThreadLocal();
Methods :
- InheritableThreadLocal is a child class of ThreadLocal and hence all method’s present in ThreadLocal by default available to InheritableThreadLocal.
- In addition to InheritableThreadLocal it contains only 1 method
Object childValue(Object parentValue)
.
package com.example.thread;/**
* @author code.factory
*
*/
public class ThreadLocalTest {
public static void main(String... args) {
ParentThread pt = new ParentThread();
pt.start();
}
}class ParentThread extends Thread {
public static InheritableThreadLocal l = new InheritableThreadLocal() {
public Object childValue(Object p) {
return "Child";
}
};
public void run() {
l.set("Parent");
System.out.println("Parent thread value : " + l.get());
ChildThread ct = new ChildThread();
ct.start();
}
}class ChildThread extends Thread {
public void run() {
System.out.println("Child thread value : " + ParentThread.l.get());
}
}
Output :
Parent thread value : Parent
Child thread value : Child
- In the above program if replace InheritableThreadLocal with the ThreadLocal and if we are not overriding childValue() method then the output is
Parent thread value : Parent
Child thread value : null
- In the above program if we are maintaining InheritableThreadLocal and if we are not overriding childValue() then the output is
Parent thread value : Parent
Child thread value : Parent