How to I could set 'attributes' to current Thread in Java, I want to set key-values and get the value in another place, but in the same Thread. like to this http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html
2 Answers
I do not think you can add attributes to any given thread in Java, but you could use a ThreadLocal instance to store any special information per thread.
http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
1 Comment
Vladimir Dyuzhev
This is exactly how it is done in log4j MDC, and also EJB transaction context and security context is carried along the same way during a request -- this is one of the reasons EJB prohibits from starting own threads.
Here's sample code for @edalorzo's answer:
import java.util.HashMap;
import java.util.Map;
public class ThreadAttributes {
private static ThreadLocal<Map<String, String>> threadAttrs = new ThreadLocal<Map<String, String>>() {
@Override
protected Map<String, String> initialValue() {
return new HashMap<String, String>();
}
};
public static String get(String key) {
return threadAttrs.get().get(key);
}
public static void set(String key, String value) {
threadAttrs.get().put(key, value);
}
}
To use it just this:
ThreadAttributes.get("attribute"); //to get an attribute
ThreadAttributes.set("attribute", "toValue"); //to set an attribute
Warning: if you application creates lots threads and does not reuse them this code will potentially leak HashMaps.
2 Comments
Edwin Dalorzo
On the other hand ThreadLocal variables tend to have problems with thread pools, since when a tread from the pool is re-used it will be assigned the same thread local variable as the last time it was in use. Therefore, it is important to check this is not an issue.
rodion
That's very true. I guess it really depends on what is the requirement. If you need attributes that are task-scoped (
Runnable#run()-scoped, for instance) it might be worth looking at source code for Google Guice framework, which allowes you to scope instances.