#java #multithreading
#java #многопоточность
Вопрос:
Как я мог бы установить для ‘ attributes
‘ значение current Thread
в Java, я хочу установить ключевые значения и получить значение в другом месте, но в том же потоке. нравится это http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html
Ответ №1:
Я не думаю, что вы можете добавлять атрибуты к какому-либо заданному потоку в Java, но вы могли бы использовать ThreadLocal
экземпляр для хранения какой-либо специальной информации для каждого потока.
http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
Комментарии:
1. Именно так это делается в log4j MDC, а также контекст транзакции EJB и контекст безопасности передаются таким же образом во время запроса — это одна из причин, по которой EJB запрещает запускать собственные потоки.
Ответ №2:
Вот пример кода для ответа @edalorzo:
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);
}
}
Чтобы использовать его только так:
ThreadAttributes.get("attribute"); //to get an attribute
ThreadAttributes.set("attribute", "toValue"); //to set an attribute
Предупреждение: если ваше приложение создает множество потоков и не использует их повторно, этот код потенциально может привести к утечке HashMap
s.
Комментарии:
1. С другой стороны, локальные переменные потоков, как правило, имеют проблемы с пулами потоков, поскольку при повторном использовании потока из пула ему будет присвоена та же локальная переменная потока, что и при последнем использовании. Поэтому важно убедиться, что это не проблема.
2. Это очень верно. Я думаю, это действительно зависит от того, что является требованием. Если вам нужны атрибуты, зависящие от задач (например, с
Runnable#run()
-scoped), возможно, стоит взглянуть на исходный код Google Guice framework, который позволяет вам создавать экземпляры с областью видимости.