Beruflich Dokumente
Kultur Dokumente
http://www.ibm.com/developerworks/java/library/j-thread...
English
Technical topics
Evaluation software
Community
Events
1 of 7
10/24/2012 03:17 PM
http://www.ibm.com/developerworks/java/library/j-thread...
public class ThreadLocal { public Object get(); public void set(Object newValue); public Object initialValue(); }
The get() accessor retrieves the current thread's value of the variable; the set() accessor modies the current thread's value. The initialValue() method is an optional method that lets you set the initial value of the variable if it has not yet been used in this thread; it allows for a form of lazy initialization. How ThreadLocal behaves is best illustrated by an example implementation. Listing 2 shows one way to implement ThreadLocal. It isn't a particularly good implementation (although it is quite similar to the initial implementation), as it would likely perform poorly, but it illustrates clearly how ThreadLocal behaves. Listing 2. Bad implementation of ThreadLocal
public class ThreadLocal { private Map values = Collections.synchronizedMap(new HashMap()); public Object get() { Thread curThread = Thread.currentThread(); Object o = values.get(curThread); if (o == null && !values.containsKey(curThread)) { o = initialValue(); values.put(curThread, o); } return o; } public void set(Object newValue) { values.put(Thread.currentThread(), newValue); } public Object initialValue() { return null; } }
This implementation will perform poorly because it requires synchronization on the values map for each get() and set() operation, and if multiple threads are accessing the same ThreadLocal at once, there will be contention. Additionally, this implementation is impractical because using Thread objects as the key in the values map will prevent the Thread from being garbage collected after the thread exits, and the thread-specic values of the ThreadLocal for deceased threads will also not be garbage collected. Using
ThreadLocal
Thread-local variables are commonly used to render stateful Singleton or shared objects thread-safe, either by encapsulating the entire unsafe object in a ThreadLocal or by encapsulating the object's thread-specic state in a ThreadLocal. For example, in an application that is tightly tied to a database, many methods may need to access the database. It could be inconvenient to include a Connection as an argument to every method in the system -- a sloppier, but signicantly more convenient technique would be to access the connection with a Singleton. However, multiple threads cannot safely share a JDBC Connection. By using a ThreadLocal in our Singleton, as shown in Listing 3, we can allow any class in our program to easily acquire a reference to a per-thread Connection. In this way, we can think of a ThreadLocal as allowing us to create a per-thread-singleton. Listing 3. Storing a JDBC Connection in a per-thread Singleton
public class ConnectionDispenser { private static class ThreadLocalConnection extends ThreadLocal { public Object initialValue() { return DriverManager.getConnection(ConfigurationSingleton.getDbUrl()); }
2 of 7
10/24/2012 03:17 PM
http://www.ibm.com/developerworks/java/library/j-thread...
private static ThreadLocalConnection conn = new ThreadLocalConnection(); public static Connection getConnection() { return (Connection) conn.get(); } }
Any stateful or non-thread-safe object that is relatively more expensive to create than to use, such as a JDBC Connection or a regular-expression matcher, is a good candidate for the per-thread-singleton technique. Of course, for situations like this, you can use other approaches, like pooling, for safely managing shared access. However, even pooling has some potential drawbacks from a scalability perspective. Because pool implementations must synchronize to maintain the integrity of the pool data structures, if all threads are using the same pool, program performance may suer due to contention in a system with many threads accessing the pool frequently. Using
ThreadLocal
Other applications for ThreadLocal in which pooling would not be a useful alternative include storing or accumulating per-thread context information for later retrieval. For example, suppose you wanted to create a facility for managing debugging information in a multithreaded application. You could accumulate debugging information in a thread-local container as shown by the DebugLogger class in Listing 4. At the beginning of a unit of work, you empty the container, and when an error occurs, you query the container to retrieve all the debugging information that has been generated so far by this unit of work. Listing 4. Using ThreadLocal for managing a per-thread debugging log
public class DebugLogger { private static class ThreadLocalList extends ThreadLocal { public Object initialValue() { return new ArrayList(); } public List getList() { return (List) super.get(); } } private ThreadLocalList list = new ThreadLocalList(); private static String[] stringArray = new String[0]; public void clear() { list.getList().clear(); } public void put(String text) { list.getList().add(text); } public String[] get() { return list.getList().toArray(stringArray); } }
Throughout your code, you can call DebugLogger.put(), saving information about what your program is doing, and you can easily retrieve the debugging information relevant to a particular thread later when necessary (such as when an error has occurred). This technique is a lot more convenient and ecient than simply dumping everything to a log le and then trying to sort out which log records come from which thread (and worrying about contention for the logging object between threads.) is also useful in servlet-based applications or any multithreaded server application in which the unit of work is an entire request, because then a single thread will be used during the entire course of handling the request. You can use ThreadLocal variables to store any sort of per-request context information using the per-thread-singleton technique described earlier.
ThreadLocal
3 of 7
10/24/2012 03:17 PM
http://www.ibm.com/developerworks/java/library/j-thread...
InheritableThreadLocal
The ThreadLocal class has a relative, InheritableThreadLocal, which functions in a similar manner, but is suitable for an entirely dierent sort of application. When a thread is created, if it holds values for any InheritableThreadLocal objects, these values are automatically passed on to the child process as well. If a child process calls get() on an InheritableThreadLocal, it sees the same object as the parent would. To preserve thread-safety, you should use InheritableThreadLocal only for immutable objects (objects whose state will not ever be changed once created), because the object is shared between multiple threads. InheritableThreadLocal is useful for passing data from a parent thread to a child thread, such as a user id, or a transaction id, but not for stateful objects like JDBC Connections.
ThreadLocal
performance
oers a number of benets. It is often the easiest way to render a stateful class thread-safe, or to encapsulate non-thread-safe classes so that they can safely be used in multithreaded environments. Using ThreadLocal allows us to bypass the complexity of determining when to synchronize in order to achieve threadsafety, and it improves scalability because it doesn't require any synchronization. In addition to simplicity, using ThreadLocal to store a per-thread-singleton or per-thread context information has a valuable documentation perk -by using a ThreadLocal, it's clear that the object stored in the ThreadLocal is not shared between threads, simplifying the task of determining whether a class is thread-safe or not.
4 of 7
10/24/2012 03:17 PM
http://www.ibm.com/developerworks/java/library/j-thread...
Java Performance Tuning by Jack Shirazi (O'Reilly & Associates, 2000) provides guidance on eliminating performance issues in the Java platform. Java Platform Performance: Strategies and Tactics by Steve Wilson and Je Kesselman (Addison-Wesley, 2000) oers techniques for the experienced Java programmer to build speedy and ecient Java code. Java Performance and Scalability, Volume 1: Server-Side Programming Techniques by Dov Bulka (AddisonWesley, 2000) provides a wealth of tips and tricks designed to help you increase the performance of your apps. Brian Goetz' article "Double-checked locking: Clever, but broken" (JavaWorld, February 2001) explores the Java Memory Model (JMM) in detail and the surprising consequences of failing to synchronize in certain situations. Doug Lea's Concurrent Programming in Java, Second Edition (Addison-Wesley, 1999) is a masterful book on the subtle issues surrounding multithreaded programming in the Java language. In his article "Writing multithreaded Java applications" (developerWorks, February 2001), Alex Roetter introduces the Java Thread API, outlines issues involved in multithreading, and oers solutions to common problems. The performance modeling and analysis team at IBM Thomas J. Watson Research Center is researching several projects in the areas of performance and performance management. Find more Java technology resources in the developerWorksJava technology zone. About the author Brian Goetz is a software consultant and has been a professional software developer for the past 15 years. He is a Principal Consultant at Quiotix, a software development and consulting rm located in Los Altos, CA. See a list of Brian's published and upcoming articles in popular industry publications. Close [x]
developerWorks: Sign in
If you don't have an IBM ID and password, register here. IBM ID: Forgot your IBM ID? Password: Forgot your password? Change your password After sign in: Stay on the current page Keep me signed in. By clicking Submit, you agree to the developerWorks terms of use.
Submit
Cancel
The rst time you sign into developerWorks, a prole is created for you. This prole includes the rst name, last name, and display name you identied when you registered with developerWorks. Select information in your developerWorks prole is displayed to the public, but you may edit the information at any time. Your
5 of 7
10/24/2012 03:17 PM
http://www.ibm.com/developerworks/java/library/j-thread...
rst name, last name (unless you choose to hide them), and display name will accompany the content that you post. All information submitted is secure. Close [x]
Submit
Cancel
All information submitted is secure. Average rating (242 votes) 1 star 2 stars 3 stars 4 stars 5 stars 1 star 2 stars 3 stars 4 stars 5 stars
Submit
Add comment: Sign in or register to leave a comment. Note: HTML elements are not supported within comments.
Post
Total comments (4) Mr. Brian, I had a passing thought about creating a per thread singleton object for JDBC connection- won't it be easier to just abstract creation part in separate class, just like we do for a standard singleton class, but without a Synchronized keyword? This way we can call getInstance from any place in our program whenever a connection is required. If this is a valid approach to take, then the choice just boils down between choosing a standard singleton (minus
6 of 7
10/24/2012 03:17 PM
http://www.ibm.com/developerworks/java/library/j-thread...
Ditto! This post may be a few years old, but it really helped me out. Thank you! :-) Posted by [JDRSM]DrewB on 01 April 2010 Report abuse class DebugLogger is not tested. Methods put, get, and clear should be static. stringArray is not used. Posted by rfq on 27 February 2010 Report abuse Although it's a quite old article, it really helped me understanding ThreadLocal, and learning more about Java Threading. Thank you Mr. Goetz! Posted by Kinow on 13 December 2009 Report abuse
Print this page Share this page Follow developerWorks
Technical topics
AIX and UNIX Information Management Lotus Rational Tivoli WebSphere Java technology Linux Open source SOA and web services Web development XML
Evaluation software
By IBM product By evaluation method By industry
Community
Forums Groups Blogs Wikis
About developerWorks
Site help and feedback Contacts Article submissions
IBM
Solutions Software Software services Support
Events
Briefings Webcasts Find events
Related resources
Students and faculty Business Partners
More...
More...
7 of 7
10/24/2012 03:17 PM