Saturday, July 17, 2010

How to use ThreadLocal


Target audience: Beginners and Intermediates

ThreadLocal is a class provides way to hold thread local variables and provide access to get and set values. in other words, it allows you to have copy of variables per thread and these variables will be garbage collected when the associated thread dies. ThreadLocal instances are advised to be private static fields in classes.For example, check the Audit class bellow
class Audit {
private static ThreadLocal auditDetails = new ThreadLocal();

public static String get() {
return (String) auditDetails.get();
}

public static void set(String details) {
auditDetails.set(details);
}
}

Here, auditDetails is a thread local variable. The set(String) method of Audit class sets a value in thread local variable auditDetails. As auditDetails is a static, it will be shared with multiple threads but the value which is set will belong to only the current thread.The JVM finds the current thread and associate the value. And when get(String) method of Audit is called, the auditDetails returns the value associated with current thread. The following example will help you to understand it more.

package basics;

public class ThreadLocalExamples {

public void methodA() {

//Generates a random value
int value = (int)(Math.random()*100);

//Prints the current thread and the generated random value
System.out.println("Setting " +value+ " to " +Thread.currentThread().getName());

//Set the random value as audit details
Audit.set(String.valueOf(value));

//Keeping the threads on sleep mode for some time
try {
Thread.sleep(value);
} catch (InterruptedException e) {
e.printStackTrace();
}
methodB();
}

public void methodB() {

//Just prints the audit details value set for the current thread
System.out.println(Thread.currentThread().getName()+":"+Audit.get());
}

public static void main(String[] args) {

final ThreadLocalExamples examples = new ThreadLocalExamples();

//Creates thread one and call methodA() on examples
Thread threadOne = new Thread() {
public void run() {
examples.methodA();
}
};

//Creates thread two and call methodA() on the same instance examples
threadOne.setName("ThreadOne");
Thread threadTwo = new Thread() {
public void run() {
examples.methodA();
}
};
threadTwo.setName("ThreadTwo");

//Starting the threads
threadOne.start();
threadTwo.start();
}
}
if you look at the code, there are two methods methodA() and methodB().The methodA() generates a random number and set it as audit details and calls the methodB().The static method set(string) in Audit class is called to set audit details to the thread local .The methodB() gets the audit details and prints it. The static method get() in Audit class is called to get audit details from thread local. The main method creates creates one instance of ThreadLocalExamples and two instances of threads. Both thread instances call the methodA() of same instance of ThreadLocalExamples in their run() method.
Note: The same instance of ThreadLocalExamples is accessed by two threads at the same time.
If you run the program, you will get something like the following output
Setting 13 to ThreadOne
Setting 67 to ThreadTwo
ThreadOne:13
ThreadTwo:67


if you analyze the output results, Thread one sets ‘13 ‘ to thread local, then Thread two sets ‘67 ‘ to thread local.Even though both threads access the same thread local instance to set the value. the values are set to the current thread’s local values. That’s why when it prints the value, the value associated to the current thread is retrieved and printed.

So one again i say it, ThreadLocal is a class provides way to hold thread local variables and provide access to get and set values. in other words, it allows you to have copy of variables per thread and these variables will be garbage collected what the thread dies.

No comments:

Post a Comment