为当前Java线程添加属性

8
2个回答

14

2
这正是log4j MDC的实现方式,同时EJB事务上下文和安全上下文在请求期间也是以同样的方式传递 - 这也是EJB禁止启动自己的线程的原因之一。 - Vladimir Dyuzhev

7
以下是@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


2
另一方面,ThreadLocal 变量在使用线程池时往往会出现问题,因为当从池中重新使用线程时,它将被分配与上次使用时相同的 ThreadLocal 变量。因此,重要的是要检查这是否是一个问题。 - Edwin Dalorzo
1
这是非常正确的。我猜这真的取决于需求是什么。如果你需要任务范围的属性(例如Runnable#run()的范围),那么看一下Google Guice框架的源代码可能是值得的,它允许你对实例进行作用域限定。 - rodion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接