may well never need, but if you do need it THReadLocal may simplify your work.
For example, you might want to have a user object associated with all operations, set on a per-thread basis.
You could create a ThreadLocal object to hold each thread's current user object:
public class Operations {
private static ThreadLocal
new ThreadLocal
/* Initially start as the "unknown user". /
protected User initialValue() {
return User.UNKNOWN_USER;
}
};
private static User currentUser() {
return users.get();
}
public static void setUser(User newUser) {
users.set(newUser);
}
public void setValue(int newValue) {
User user = currentUser();
if (!canChange(user))
throw new SecurityException();
// ... modify the value ...
}
// ...
}
The static field users holds a ThreadLocal variable whose initial value in each thread will be
User.UNKNOWN_USER. This initial value is defined by overriding the method initialValue, whose
default behavior is to return null. The programmer can set the user for a given thread by invoking
setUser. Once set, the method currentUser will return that value when invoked in that thread. As
shown in the method setValue, the current user might be used to determine privileges.
You can clear the value in a ThreadLocal by invoking its remove method. If get is invoked again, then
initialValue will again be used to determine what to return.
When a thread dies, the values set in THReadLocal variables for that thread are not reachable, and so can be
collected as garbage if not otherwise referenced.
When you spawn a new thread, the values of THReadLocal variables for that thread will be the value
returned by its initialValue method. If you want the value in a new thread to be inherited from the
spawning thread, you can use the class InheritableThreadLocal, a subclass of THReadLocal. It has
a protected method childValue that is invoked to get the child's (spawned thread's) initial value. The
method is passed the parent's value for the variable and returns the value for the child. The default
implementation of childValue returns the parent's value, but you can subclass to do something different,
such as cloning the parent's value for the child.
Use of ThreadLocal objects is an inherently risky tool. You should use them only where you thoroughly
understand the thread model that will be used. The problems arise with thread pooling, a technique that is
sometimes used to reuse threads instead of creating new ones for each task. In a thread pooling system a
thread might be used several times. Any ThreadLocal object used in such an environment would contain
the state set by the last code that happened to use the same thread, instead of an uninitialized state expected at
the beginning of a new thread of execution. If you write a general class that uses ThreadLocal objects and