使用 ThreadLocal

Java Concurrency 中一個有用的工具是 ThreadLocal - 這允許你擁有一個對給定執行緒唯一的變數。因此,如果相同的程式碼在不同的執行緒中執行,則這些執行將不共享該值,而是每個執行緒都有自己的執行緒本地變數。

例如,這經常用於建立處理 servlet 中的請求的上下文(例如授權資訊)。你可能會這樣做:

private static final ThreadLocal<MyUserContext> contexts = new ThreadLocal<>();

public static MyUserContext getContext() {
    return contexts.get(); // get returns the variable unique to this thread
}

public void doGet(...) {
    MyUserContext context = magicGetContextFromRequest(request); 
    contexts.put(context); // save that context to our thread-local - other threads
                           // making this call don't overwrite ours
    try {
        // business logic
    } finally {
        contexts.remove(); // 'ensure' removal of thread-local variable
    }
}

現在,你可以在需要的地方使用 MyServlet.getContext(),而不是將 MyUserContext 傳遞到每個方法中。當然,這確實引入了一個需要記錄的變數,但它是執行緒安全的,這消除了使用這種高範圍變數的許多缺點。

這裡的關鍵優勢是每個執行緒在 contexts 容器中都有自己的執行緒區域性變數。只要你從定義的入口點使用它(比如要求每個 servlet 維護其上下文,或者可能通過新增 servlet 過濾器),你可以在需要時依賴此上下文。