
Java 25 是一个 LTS 版本,它的众多新特性中就数
JEP 506: Scoped Values能改变我们从前使用ThreadLocal时的编程范式。因其重要性,所以单列一篇来专门学习它。Scoped Values, 可用来替代ThreadLocal的使用,特别是在虚拟线程当中。Scoped Values用于在当前线程或子线程中共享不可变的数据,说到不可变的数据就会想到JEP 502: Stable Values (Preview).ThreadLocal, 甚至InheritableThreadLocal用于子线程中共享数据还是有些挑战性,特别碰到线程池的情况, 而且ThreadLocal不在乎数据可变还是不可变的,执行当中谁改了数据,不知道。Scoped Values的 JEP 说其目的不是用来完全替代ThreadLocal。下面来看看
Scoped Values如何在子线程中共享数据,它还能与虚拟线程的结构化并发配合使用。ThreadLocal/InteritableThreadLocal仍然是很多框架用来在线程中(间)共享数据的办法,在Spring框架中有大量的使用, 如XxxContextHolder之类的。目前的ThreadLocal存在一些问题- ThreadLocal 中的数据是可变的,多数应用场景只要不可变的数据
- 难以管理共享数据的生命周期,特别是在线程池中,线程被重用时,ThreadLocal 中的数据可能会被意外共享或泄露。由使用方主动清除数据,更是会造成潜在的 Bug
- 成本高昂,创建子线程,或线程切换时要对共享数据进行复制,
VirtualThread也是继承自Thread, 所以虚拟线程也能用ThreadLocal。 一旦虚拟线程的数量达到成千上万,十百万的级别时,ThreadLocal数据不停复制的代价就很高了