hooyantsing's Blog

0x000F-ThreadLocal实战经验

2023/08/06

问题详解

ThreadLocalMap 底层结构

640

每个线程 Thread 都维护了自己的 threadLocals 变量,所以在每个线程创建 ThreadLocal 的时候,实际上数据是存在自己线程 Thread 的 threadLocals 变量里面的,别人没办法拿到,从而实现了隔离。

ThreadLocalMap 是由 数组 实现。

ThreadLocalMap 如何解决哈希冲突

641

解决哈希冲突:开放定址法

新思路

使线程不安全的资源对象线程安全

  • 为每一个对象分配一个线程不安全对象,但会生成大量重复资源对象;

  • 用锁保证某一时刻仅有一个线程可对线程不安全对象操作,但锁会影响性能。

为每个线程创建一个独享的线程不安全的资源对象,那资源对象就是线程安全的了。

方法形参传递

  • 通常是为方法形参列表追加参数的形式扩张传递参数,但涉及第三方依赖时不可更改参数。

将参数 set 到 ThreadLocal 里可以避免重写被调用方法的形参列表,传递到使用位置再 get 出来。

父子线程参数传递

  • 通常是实现一个 Thread 子类,用构造器传参的方式传递父线程参数。

通过 ThreadLocal 子类 InheritableThreadLocal 共享线程数据。

在开源框架的应用

Spring

Spring采用 Threadlocal 的方式,来保证单个线程中的数据库操作使用的是同一个数据库连接,同时,采用这种方式可以使业务层使用事务时不需要感知并管理 connection 对象,通过传播级别,巧妙地管理多个事务配置之间的切换,挂起和恢复。

主要是在 TransactionSynchronizationManager 这个类里面。Spring 的事务主要是 ThreadLocalAOP 去做实现的。

参考阅读

CATALOG
  1. 1. 问题详解
    1. 1.1. ThreadLocalMap 底层结构
    2. 1.2. ThreadLocalMap 如何解决哈希冲突
    3. 1.3. 新思路
      1. 1.3.1. 使线程不安全的资源对象线程安全
      2. 1.3.2. 方法形参传递
      3. 1.3.3. 父子线程参数传递
    4. 1.4. 在开源框架的应用
      1. 1.4.1. Spring
  2. 2. 参考阅读