2011-12-18 30 views
1

我想使用InheritableThreadLocal來存儲一些變量。所以我寫了一些像這樣的代碼:NullPointerException可能與InheritableThreadLocal有關

public class ThreadContext 
{ 
    private static ThreadLocal current = new InheritableThreadLocal(); 

    public static HashMap getContext() 
    { 
     if (current.get() == null) { 
      createContext(); 
     } 
     return (HashMap) current.get(); 
    } 

    public static void createNewContext(){ 
     createContext(); 
    } 

    public static IClientContext getClientContext() 
    { 
     return (IClientContext) ThreadContext.getContext().get("CLIENT_CONTEXT"); 
    } 

    public static void setClientContext(IClientContext ctx) { 
     ThreadContext.getContext().put("CLIENT_CONTEXT", ctx); 
    } 

    private static void createContext() 
    { 
     current.set(new HashMap()); 
    } 
} 

但是,當其他代碼調用getClientContext,NullPointerException異常時有發生:

java.lang.NullPointerException 
    at com.xxx.util.ThreadContext.getClientContext(ThreadContext.java:19) 

它看起來像的getContext返回空值。但在getContext中,它不能返回null。 因爲如果get返回null,它會創建一個新的。

public static HashMap getContext() 
{ 
    if (current.get() == null) { 
     createContext(); 
    } 
    return (HashMap) current.get(); 
} 

以前有人遇到過這個問題嗎?或者有什麼想法?

回答

2

我不知道這是否解決您的問題,但寫這更明確的方式是

public class ThreadContext { 
private static ThreadLocal<Map<String, IClientContext>> current = new InheritableThreadLocal<Map<String, IClientContext>>() { 
    protected Map<String, IClientContext> initialValue() { 
     return new LinkedHashMap<String, IClientContext>(); 
    } 
}; 

public static IClientContext getClientContext(){ 
    return ThreadContext.getContext().get("CLIENT_CONTEXT"); 
} 

這將意味着你使用初始化線程局部值的支持方式。

+1

+1使代碼線程安全。 OP的代碼可以將兩個不同的地圖返回給兩個線程。但我不明白他如何獲得NPE。 – 2011-12-18 09:04:08

+0

@JBNizet同意,但如果他正在做某件事,他並不是說它應該取代它。 – 2011-12-18 09:13:40

+0

@PeterLawrey感謝您的建議。我也想知道爲什麼要使用LinkedHashMap? – crabhit 2011-12-19 02:22:22