Home  Synchronization and concurrency  wait/notify  final  volatile  synchronized keyword  Java threading  Deadlock (and avoiding it)  Java 5: ConcurrentHashMap  Atomic variables  Explicit locks  Queues  Semaphores  CountDownLatch  CyclicBarrier

Thread-local variables in Java (ctd)

On the previous page, we saw an example of using ThreadLocal to pool Calendar objects. On this page, we consider what are the general criteria for choosing ThreadLocal?

When to use ThreadLocal?

So what are other good candidates for object re-use via ThreadLocal? Basically, objects where:

  • The objects are non-trivial to construct;
  • An instance of the object is frequently needed by a given thread;
  • The application pools threads, such as in a typical server (if every time the thread-local is used it is from a new thread, then a new object will still be created on each call!);
  • It doesn't matter that Thread A will never share an instance with Thread B;
  • It's not convenient to subclass Thread. If you can subclass Thread, you could add extra instance variables to your subclass instead of using ThreadLocal. But for example, if you are writing a servlet running in an off-the-shelf servlet runner such as Tomcat, you generally have no control over the class of created threads. Of course, even if you can subclass Thread, you may simply prefer the cleaner syntax of ThreadLocal.

That means that typical objects to use with ThreadLocal could be:

  • Random number generators (provided a per-thread sequence was acceptable);
  • Collators;
  • native ByteBuffers (which in some environments cannot be destroyed once they're created);
  • XML parsers or other cases where creating an instance involves going through slightly non-trival code to 'choose a registered service provider';
  • Per-thread information such as profiling data which will be periodically collated.

Note that it is generally better not to re-use objects that are trivial to construct and finalize. (By "trivial to finalize", we mean objects that don't override finalize.) This is because recent garbage collector implementations are optimised for "temporary" objects that are constructed, trivially used and then fall out of scope without needing to be added to the finalizer queue. Pooling something trivial like a StringBuffer, Integer or small byte array can actually degrade performance on modern JVMs.

Article written by Neil Coffey (@BitterCoffey).

Software

 LetterMeister (word puzzle game for iPhone)
 Currency Quoter (currency converter/predictor)
 French Vocab Games for iPhone/iPad
 Vocabularium: create Spanish vocab podcasts


Java programming articles and tutorials on this site are written by Neil Coffey (@BitterCoffey). Suggestions are always welcome if you wish to suggest topics for Java tutorials or programming articles, or if you simply have a programming question that you would like to see answered on this site. Most topics will be considered. But in particular, the site aims to provide tutorials and information on topics that aren't well covered elsewhere, or on Java performance information that is poorly described or understood. Suggestions may be made via the Javamex blog (see the site's front page for details).
Copyright © Neil Coffey 2015. All rights reserved.