OpenJDK: Project Loom

互斥:锁

现在对象锁不尊重虚拟线程,但是 JUC 下的锁是尊重虚拟线程的。

共享:ScopedValue

ThreadLocal 和虚拟线程配合的不是很好,尽管功能上 ThreadLocal 是支持虚拟线程的,但是由于虚拟线程数量众多、生命周期短,使用 ThreadLocal 时虽然保证了线程安全,却创建了大量对象——这个问题在平台线程上就不明显。JEP 429 ScopedValues (Java 20) 是为了解决这个问题的。

💡 ThreadLocal 和线程池配合的也不是很好,因此短期任务结束后,将线程放回池中之前要及时清理数据。

ScopedValue 用 where 绑定共享变量,用 call 来启动虚拟线程,这样虚拟线程及子虚拟线程能够在调用环境中通过之前捕获的键(图中为 KEY)来获取值,这里使用方式也类似于之前的 ThreadLocal 查表。于是,一些本可以共享的变量实现了共享。

另外,ScopedValue 没有 remove() 方法,因为 .call() 返回后 KEY 就随着虚拟线程结束而解绑了。如果直接获取而对应值不存在,则会抛出异常;有必要时用 isBound() 来检查。

ScopedValue 要么是 unbound,要么是在创建虚拟线程之前就已经确定下来,并且引用不可更改。

同步:StructuredTaskScope

用来组织一组任务,可以调用 join() 来等待 scope 完成任务。这样能够达到类似于 await/async 的逻辑。