天天看点

Java ThreadLocal源码学习前言设计思路核心代码后记

ThreadLocal源码学习

  • 前言
  • 设计思路
  • 核心代码
  • 后记

前言

定义:ThreadLocal是线程本地变量访问对象。(注: 线程本地变量与当前线程绑定到一起的变量,在其他线程中无法访问。)

作用:Java中执行任何方法都是在线程中执行的,由执行方法的线程来提供方法执行的上下文,那么我们如何在这个上下文中添加一些变量呢?答案就是使用ThreadLocal。ThreadLocal的应用场景: Trace追踪,事务管理器等等。

设计思路

Java ThreadLocal源码学习前言设计思路核心代码后记

步骤说明(加入我们需要通过ThreadLocalA向当前线程中存数据):

  1. 通过Thread.currentThread()方法获取当前线程对象。
  2. 由于ThreadLocal与Thread同一包下,ThreadLocal可以直接访问Thread对象中的ThreadLocalMap对象。
  3. 新建Entry对象,之后存放到ThreadLocalMap的entry[i]中, 具体位置由ThreadLocal中的threadLocalHashCode值&size的方式定位。

这里我想解释下Entry为什么要设计成继承WeakReference类,因为如果将Entry对象设计成强引用,那么在我们外部释放对ThreadLocal的引用时,Entry还保持这对ThreadLocal的强引用那么ThreadLocal这个对象将不会被释放,以及Entry中的value对象,造成内存泄漏问题。

核心代码

Java ThreadLocal源码学习前言设计思路核心代码后记
Java ThreadLocal源码学习前言设计思路核心代码后记
Java ThreadLocal源码学习前言设计思路核心代码后记
Java ThreadLocal源码学习前言设计思路核心代码后记
Java ThreadLocal源码学习前言设计思路核心代码后记

后记

一个线程本地变量的存储与访问大体上涉及到如下几个对象

ThreadLocal(访问能力), ThreadLocalMap(本地变量的实际存储), Thread(持有ThreadLocalMap对象用于做到线程隔离)。

  • 每个ThreadLocal对象之间是相互隔离的,即使访问同一个线程的本地变量也只能访问由自己存放的数据。
  • ThreadLocal提供了Thread本地变量的访问能力(并不提供储存)。本地变量是存储在了Thread(提供多个ThreadLocal之间的数据隔离,以及线程隔离)对象持有的ThreadLocal.ThreadLocalMap(提供存储能力)对象中。
  • Thread对象的ThreadLocalMap设置成包访问权限可以保证,线程本地对象不会被其他包class对象访问,而又不对ThreadLocal造成影响。
  • 为什么ThreadLocalMap要Thread对象持有,而不设计成ThreadLocal对象持有?如果设计到ThreadLocal中第一个是我们不能对当前线程所引用的ThreadLocal进行管理,第二个是Thread对象所有本地变量的管理。