Thread-local variables in Java
In some cases, an alternative to synchronization is available in the form
of thread-local variables. The technique has probably been a little
overlooked in Java because in early JVMs, their implementation didn't take advantage
of operating system support and actually didn't provide much performance advantage.
But in later implementations (from around Java 1.4 onwards)
they can provide a significant advantage in some cases.
So what is a thread-local variable? A thread-local variable is one whose value
at any one time is linked to which thread it is being accessed from. In other
words, it has a separate value per thread. Each thread maintains its own, separate
map of thread-local variable values. (Many operating systems actually have native
support for thread-local variables, but in Sun's implementation at least,
native support is not used, and thread-local variables are instead held in a specialised
type of hash table attached to the Thread.)
Thread-local variables are used via the ThreadLocal class in Java.
We declare an instance of ThreadLocal, which has a get() and
set() method. A call to these methods will read and set the calling
thread's own value. So in this example, the two threads will effectively each
have its own counter, incremented independently of the other thread:
final ThreadLocal perThreadCounter = new ThreadLocal();
Thread t1 = new Thread() {
public void run() {
perThreadCounter.set(new Integer(0));
while (true) {
Integer prevCount = (Integer) perThreadCounter.get();
perThreadCounter.set(new Integer(prevCount.intValue() + 1));
}
}
}
Thread t2 = new Thread() {
public void run() {
perThreadCounter.set(new Integer(0));
while (true) {
Integer prevCount = (Integer) perThreadCounter.get();
perThreadCounter.set(new Integer(prevCount.intValue() + 1));
}
}
}
t1.start();
t2.start();
Using ThreadLocal in Java 5
In Java 5 onwards, ThreadLocal has been adapted to support generics.
This means you can write something like:
ThreadLocal<Calendar> calendarCache = new ThreadLocal<Calendar>();
Now on future accesses, we can do away with the cast:
Calendar cal = calendarCache.get();
On the next page, we look at a full example of using
ThreadLocal.
If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.
Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.