知优码

您现在的位置是:首页 > 开源项目 > 项目经验

项目经验

如何正确使用ThreadLocal变量

2021-03-29项目经验
如何正确使用ThreadLocal变量

一、概述

什么时候应该使用ThreadLocal变量?

如何使用?

二、详解

一种可能的(并且是常见的)用法是,当您有一些不是线程安全的对象,但又希望避免同步对该对象的访问时。而是给每个线程自己的对象实例。

例如:

public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}

许多框架使用ThreadLocals来维护一些与当前线程相关的上下文。例如,当当前事务存储在ThreadLocal中时,您不需要通过每个方法调用将它作为参数传递,以防堆栈中有人需要访问它。Web应用程序可以在ThreadLocal中存储有关当前请求和会话的信息,以便该应用程序可以轻松访问它们。使用Guice,您可以在为注入的对象实现自定义范围时使用ThreadLocals (Guice的默认servlet范围很可能也使用它们)。

ThreadLocals是一种全局变量(尽管邪恶程度稍低,因为它们仅限于一个线程),因此在使用它们时应小心避免不必要的副作用和内存泄漏。设计您的API,以便在不再需要ThreadLocal值时将始终自动清除它们,并且不会错误使用API​​(例如,如下所示)。ThreadLocals可以用来使代码更清洁,在某些罕见的情况下,他们是做什么工作的唯一方法(我当前的项目有两个这样的情况下,它们都记录在这里下的“静态字段和全局变量”)。