• ThreadLocal class provides ThreadLocal variables.
  • ThreadLocal class maintains values for Thread basis.
  • Each ThreadLocal object maintains separate value like userId, transactionId for each Thread that accesses that Object.
  • Thread can access its local value, manipulate its value and even can remove its value.
  • In every part of the code which is executed by the Thread we can access its local variable.

For Example Consider a servlet which invokes some business methods we have a requirement to generate a unique transationId 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 separate transactionId for every request i.e., for every Thread.In every part of the code which is executed by the Thread we can access its local variable.

Note: ThreadLocal class introduced in 1.2 Version and enhanced in 1.5 version.

  • Thread Local can be associated with ThreadScope
  • Total code which is executed by thread has access to the corresponding ThreadLocal variables
  • A Thread can access its own local variables and can’t access other Threads Local variables.
  • Once Thread enters into dead state all its local variables are by default available eligible for garbage collection.

Constructor:

Threadlocal tl = new ThreadLocal();
creates a ThreadLocal variable

Methods:

Object get(): returns the value of ThreadLocal variable associated with current Thread.

Object initialValue(): returns initial value of ThreadLocal variable associated with current ThreadThe default implementation of this method is null.
to customise our own initial value, we have to override this method.

void set(Object newValue): to set a new value

void remove(): to remove the value of ThreadLocal variable associated with current Threadit is newly added method in 1.5 version after removal if we are trying to access it will be reinitialize once again by invoking its initial value method.

class ThreadLocalDemo{
    public static void main(String[] args){
         ThreadLocal tl = new ThreadLocal();
         System.out.println(tl.get()); //null
         tl.set("kalyan");
         System.out.println(tl.get()); //kalyan
         tl.remove();
         System.out.println(tl.get()); //null
    }
}

Output:
null
kalyan
null


//Overriding of initialValue() method
class ThreadLocalDemo{
    public static void main(String[] args){
        ThreadLocal tl = new ThreadLocal(){
            public Object initialValue(){
                return "kadali";
            }
        };
        System.out.println(tl.get()); //kadali
        tl.set("kalyan");
        System.out.println(tl.get()); //kalyan
        tl.remove(); 
        System.out.println(tl.get()); //kadali
    }
}

Output:
kadali
kalyan
kadali


class CustomerThread extends Thread{
    static Integer custId = 0;
    private static ThreadLocal tl = new ThreadLocal(){
        protected Integer initialValue(){
            return ++custId;
        }
    };
    CustomerThread(String name){
        super(name);
    }
    public void run(){
        System.out.println(Thread.currentThread().getName() + " executing with Customer id : " + tl.get());
    }
}
class ThreadLocalDemo{
    public static void main(String[] args){
        CustomerThread c1 = new CustomerThread("Customer Thread-1");
        CustomerThread c2 = new CustomerThread("Customer Thread-2"); 
        CustomerThread c3 = new CustomerThread("Customer Thread-3"); 
        CustomerThread c4 = new CustomerThread("Customer Thread-4"); 
        c1.start(); 
        c2.start(); 
        c3.start();
        c4.start();
    }
}

Output:
Customer Thread-1 executing with Customer id : 1
Customer Thread-3 executing with Customer id : 3
Customer Thread-2 executing with Customer id : 2
Customer Thread-4 executing with Customer id : 4

In the above program for every CustomerThread a separate CustomerId will be maintained by ThreadLocal Object.

Inherritance in ThreadLocal:

  • Parents Threads ThreadLocal variable by default not available the child Thread.
  • If we want to make Parent Threads ThreadLocal variable value available to the child Threads then we should go for InheritableThreadLocal class
  • By default child thread value is exactly same as parent thread value but we can provide customised value for child thread by overriding childValue() method.

Constructor:

InheritableThreadLocal tl = new InheritableThreadLocal();

InheritableThreadLocal is the child class of ThreadLocal and hence all methods present in ThreadLocal by default available to InheritableThreadLocal.
In addition to these methods it contains only one method.

public Object childValue(Object parentValue)

class ParentThread extends Thread{
    public static ThreadLocal tl = new ThreadLocal();
    public void run(){
        tl.set("pp");
        System.out.println("Parent Thread value is " + tl.get());
        ChildThread ct = new ChildThread();
        ct.start();
    }
}
class ChildThread extends Thread{
    public void run(){
        System.out.println("Child Thread value is " + ParentThread.tl.get());
    }
}
class ThreadLocalDemo{
    public static void main(String[] args){
        ParentThread pt = new ParentThread();
 pt.start();
    }
}

Output:
Parent Thread value is pp
Child Thread value is null


class ParentThread extends Thread{
    public static InheritableThreadLocal t1 = new InheritableThreadLocal();
    public void run(){
        t1.set("pp");
        System.out.println("Parent Thread value is " + t1.get());
        ChildThread ct = new ChildThread();
        ct.start();
    }
}
class ChildThread extends Thread{
    public void run(){
        System.out.println("Child Thread value is " + ParentThread.t1.get());
    }
}
class ThreadLocalDemo{
    public static void main(String[] args){
        ParentThread pt = new ParentThread();
        pt.start();
    }
}

Output:
Parent Thread value is pp
Child Thread value is pp


class ParentThread extends Thread{
    public static InheritableThreadLocal t1 = new InheritableThreadLocal(){
        public Object childValue(Object p){
            return "cc";
        }
    };
    public void run(){
        t1.set("pp");
        System.out.println("Parent Thread value is " + t1.get());
        ChildThread ct = new ChildThread(); 
        ct.start();
    }
}
class ChildThread extends Thread{
    public void run(){
        System.out.println("Child Thread value is " + ParentThread.t1.get());
    }
}
class ThreadLocalDemo{
    public static void main(String[] args){
        ParentThread pt = new ParentThread();
        pt.start();
    }
}

Output:
Parent Thread value is pp
Child Thread value is cc