使用 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 过滤器),你可以在需要时依赖此上下文。