Java — ThreadLocal | Code Factory

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 :

  1. ThreadLocal class introduced in 1.2v and enhanced in 1.5v.
  2. ThreadLocal can be associated with thread scope.
  3. Total code which is executed by the thread has access to the corresponding thread local variables.
  4. A thread can access it’s own local variables and can’t access other thread local variables.
  5. 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

--

--