使用 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 過濾器),你可以在需要時依賴此上下文。