美文网首页
Java ThreadLocal类详解

Java ThreadLocal类详解

作者: 代码的搬运工 | 来源:发表于2022-04-01 09:15 被阅读0次

在Java的多线程并发执行过程中,为了保证多个线程对变量的安全访问,可以将变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立值,不会出现一个线程读取变量时被另一个线程修改的现象。ThreadLocal类通常被翻译为“线程本地变量”类或者“线程局部变量”类。

1、ThreadLocal的基本使用

ThreadLocal位于JDK的java.lang核心包中。如果程序创建了一个ThreadLocal实例,那么在访问这个变量的值时,每个线程都会拥有一个独立的、自己的本地值。“线程本地变量”可以看成专属于线程的变量,不受其他线程干扰,保存着线程的专属数据。当线程结束后,每个线程所拥有的那个本地值会被释放。在多线程并发操作“线程本地变量”的时候,线程各自操作的是自己的本地值,从而规避了线程安全问题。

一个ThreadLocal实例可以形象地理解为一个Map(早期版本的ThreadLocal是这样设计的)。当工作线程Thread实例向本地变量保持某个值时,会以“Key-Value对”(即键-值对)的形式保存在ThreadLocal内部的Map中,其中Key为线程Thread实例,Value为待保存的值。当工作线程Thread实例从ThreadLocal本地变量取值时,会以Thread实例为Key,获取其绑定的Value。一个ThreadLocal实例内部结构的形象展示大致如下图所示:

Java程序可以调用ThreadLocal的成员方法进行本地值的操作,具体的成员方法如下图所示:

2、ThreadLocal的使用场景

ThreadLocal的使用场景大致可以分为以下两类:

(1)线程隔离

ThreadLocal的主要价值在于线程隔离,ThreadLocal中的数据只属于当前线程,其本地值对别的线程是不可见的,在多线程环境下,可以防止自己的变量被其他线程篡改。另外,由于各个线程之间的数据相互隔离,避免了同步加锁带来的性能损失,大大提升了并发性的性能。

ThreadLocal在线程隔离的常用案例为:可以为每个线程绑定一个用户会话信息、数据库连接、HTTP请求等,这样一个线程所有调用到的处理函数都可以非常方便地访问这些资源。

(2)跨函数传递数据

通常用于同一个线程内,跨类、跨方法传递数据时,如果不用ThreadLocal,那么相互之间的数据传递势必要靠返回值和参数,这样无形之中增加了这些类或者方法之间的耦合度。

在“跨函数传递数据”场景中使用ThreadLocal的典型案例为:可以为每个线程绑定一个Session(用户会话)信息,这样一个线程所有调用到的代码都可以非常方便地访问这个本地会话,而不需要通过参数传递。

3、ThreadLocal的使用规则

1)尽量使用private static final修饰ThreadLocal实例。使用private与final修饰符主要是为了尽可能不让他人修改、变更ThreadLocal变量的引用,使用static修饰符主要是为了确保ThreadLocal实例的全局唯一。

2)ThreadLocal使用完成之后务必调用remove()方法。这是简单、有效地避免ThreadLocal引发内存泄漏问题的方法。

相关文章

网友评论

      本文标题:Java ThreadLocal类详解

      本文链接:https://www.haomeiwen.com/subject/gcogjrtx.html