Skip to content

Latest commit

 

History

History
44 lines (24 loc) · 2.66 KB

03并发编程高级篇之一.md

File metadata and controls

44 lines (24 loc) · 2.66 KB

来源:https://gitbook.cn/books/5abef415a1a5b4123501526e/index.html

ThreadLocal 的实现原理

ThreadLocal 是在 JDK 包里面提供的,它提供了线程本地变量,也就是如果你创建了一个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的一个本地拷贝,多个线程操作这个变量的时候,实际是操作的自己本地内存里面的变量,从而避免了线程安全问题,创建一个 ThreadLocal 变量后每个线程会拷贝一个变量到自己本地内存。

子线程中获取不到父线程中设置的 ThreadLocal 变量的值

同一个 ThreadLocal 变量在父线程中设置值后,在子线程中是获取不到的。

InheritableThreadLocal 原理

为了解决上面的问题,InheritableThreadLocal 应运而生,InheritableThreadLocal 继承自 ThreadLocal,提供了一个特性,就是子线程可以访问到父线程中设置的本地变量。

JDK 并发包中 ThreadLocalRandom 类原理剖析

ThreadLocalRandom 类是 JDK7 在 JUC 包下新增的随机数生成器,它解决了 Random 类在多线程下的不足。

Random 类及其局限性

每个 Random 实例里面只有一个原子性的种子变量用来记录当前种子的值,当要生成新的随机数时,需要根据当前种子计算新种子并更新原子变量。

多线程下使用单个 Random 实例生成随机数时,多个线程同时计算新种子时会竞争同一个原子变量的更新操作,由于原子变量的更新是 CAS 操作,同时只有一个线程会成功,所以会造成大量线程自旋重试,这会降低并发性能。

所以 ThreadLocalRandown 应运而生。

ThreadLocalRandom 使用 ThreadLocal 的原理,让每个线程内持有一个本地的种子变量,该种子变量只有在使用随机数时候才会被初始化,多线程下计算新种子时候是根据自己线程内维护的种子变量进行更新,从而避免了竞争。

Spring Request Scope 作用域 Bean 中 ThreadLocal 的使用

Spring 可以在 XML 里面配置 Bean 的时候可以指定 scope 属性来配置该 Bean 的作用域为 singleton、prototype、request、session 等。

其中作用域为 request 的实现原理就是使用 ThradLocal 实现的。

如果想让某个 Bean 拥有 web 的某种作用域,除了需要配置 Bean 相应的 scope 属性外,还必须在 web.xml 中进行如下配置:

<listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>