ErCargo's Coffee Time

以大多数人的努力程度之低,根本轮不到拼天赋

Action Conquers Fear, Impetuous, Indolence and so on. (行动能够克服一切恐惧,浮躁,懒惰)


Welcome to star and fork my github

多线程之 ThreadLocal

  • Pre talk
  • ThreadLocal 是什么?解决了什么问题?
  • ThreadLocal 源码分析及实现原理
  • ThreadLocal 内存泄漏问题
  • InheritableThreadLocal 的实现原理

Pre talk

线程封闭技术

访问共享可变数据时,通常需要使用同步,同步会产生性能问题,如何避免使用同步的方式来保证线程安全问题 – 不共享数据, 如何保证数据不共享呢? 如果仅仅是在单线程内访问数据,就不会存在数据共享的问题,也就不需要数据同步。 (线程封闭: Thread Confinement, 是实现线程安全最简单的方式之一)

当某个对象被封闭在一个线程中时, 这种用法将自动实现线程安全性,即使被封闭的对象本身不是线程安全的。

线程封闭常用的场景:JDBC 的 Connection 对象(非线程安全的连接池是没有意义的)

几种线程封闭技术

  • Ad-hoc 线程封闭: 由程序来承担维护线程封闭性的职责(脆弱的)
  • 栈封闭: 通过局部变量才能访问对象,局部变量的固有属性就是封闭在执行线程中(执行线程的栈中,因为变量是在栈中,栈是线程独立的)
  • ThreadLocal: 是维持线程封闭性的规范的方法。ThreadLocal 能使线程中的某个值与保存值的对象关联起来。

ThreadLocal 是什么、解决了什么问题?

jdk1.8 ThreadLocal

粗略的解释:ThreadLocal 类提供了线程本地的实例变量。这些变量与普通变量的区别在于:每个使用该变量的线程都会初始化一个独立的副本, ThreadLocal 修饰的实例,是一个典型的和线程相关联的私有的静态变量… (能力有限翻译不出来了)

ThreadLocal 对象通常用于防止对「可变的单实例变量」或「全局变量」进行共享,如 全局的数据库连接(Connection)。

ThreadLocal 通常称为:线程本地变量/线程本地存储。ThreadLocal 提供了 get 和 set 方法,为每一个使用该变量的线程存有一份独立的副本。( get 总是返回的当前执行线程在调用 set 时设置的最新值 )

一句话总结: ThreadLocal 为每个线程提供局部变量, 每个线程都可以通过 set() get() 对这个局部变量进行操作,但不会和其他线程的局部变量产生冲突, 进而实现线程的数据隔离,保证线程安全。

另外一定要注意:

  1. ThreadLocal 不是用来解决共享对象的多线程访问问题, 通过 ThreadLocal.set() 到线程中的对象是该线程自己使用的对应,其他线程是不需要访问的,也访问不到;(各个线程中访问的是不同的对象)
  2. ThreadLocal 使得各线程能够保持各自独立的对象, 并不是通过 ThreadLocal.set() 来实现的, 而是通过 每个线程中的 new 对象的操作来创建的对象,每个线程创建一个。

最常见的 ThreadLocal 使用场景是用来解决「数据库连接」、「Session 管理」等问题。

ThreadLocal 源码分析及实现原理

set()

最近的文章

Spring Cloud 组件分析

Spring Cloud 快速开发分布式应用的工具集Spring Cloud 主要功能 功能 功能详情 组件 Distributed/versioned configuration 分布式/版本化配置管理 Spring Cloud Config; Consul; Zookeeper; Nacos Service registration and discovery ...…

继续阅读
更早的文章

多线程

进程和线程的区别抽象答案:进程是资源分配的最小单位, 线程是 CPU 调度的最小单位如何组织语言能够描述清楚呢? 一个进程可以包含多个线程 进程间难以数据共享, 但是同一进程下的不同线程是可以进行数据共享的; 进程比线程消耗更多的 CPU 资源; 进程与进程之间的运行不会相互影响, 但是线程之间会相互影响; 一个线程使用共享内存时,其他线程必须等待他结束,才能使用这块区域(互斥锁) 进程使用的内存地址可以限定使用量(信号量)………

继续阅读