2011-04-10 34 views

回答

13

我不認爲你可以添加屬性給Java中的任何給定線程,但你可以使用一個ThreadLocal實例來存儲每個線程的任何特殊信息。

http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

+1

這正是它在log4j MDC中完成的方式,並且在請求期間EJB事務上下文和安全上下文也以相同的方式進行 - 這是EJB禁止啓動自己的線程的原因之一。 – 2011-04-10 02:10:19

4

下面是@ 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。

+0

另一方面,ThreadLocal變量往往會遇到線程池的問題,因爲當從池中重新使用它時,它將被分配到與上次使用時相同的線程局部變量。因此,檢查這不是一個問題很重要。 – 2011-04-10 14:15:04

+1

這是非常真實的。我想這實際上取決於什麼要求。如果你需要屬於任務範圍的屬性(例如'Runnable#run()'-scoped),那麼可能需要查看Google Guice框架的源代碼,它允許你限制實例的範圍。 – rodion 2011-04-12 01:11:28