在多线程编程中,数据共享与线程安全是两个关键问题。共享数据可能导致线程间的竞争条件,而线程安全的实现往往需要引入复杂的同步机制,如锁或原子操作。然而,有些场景下,线程间并不需要共享数据,而是希望每个线程拥有自己的独立副本。这时,线程本地存储(Thread Local Storage, TLS)便成为一种高效的解决方案。C++11 引入了 thread_local 关键字,用于声明线程本地存储变量,极大地简化了线程本地存储的使用。
背景 Java10引入了Thread Local Handshake功能。对此功能本人看了JEP312以后还是没有一个比较清晰的认识。为此,问了一些国内的JVM专家也没有获得一个回复。 后来,我就去某特上搜索关键字,然后在相关主题下提交了我的疑问希望获取到他们的回复和帮助。 在以为要石沉大海的时候,最后有一位住在印度南部班加罗尔的兄弟回答了我的问题。 以上大概是一个基本的背景。在正式展开问题和展示回复之前,我们还是要对Java10中的这个新的功能做一个基本的铺垫。 Safepoint及其不足 Safep
概述 This class provides thread-local variables. initialValue() /** * Returns the current thread's "initial value" for this * thread-local variable * * @return the initial value for this thread-local */ protected T initialValue() get() /** * Returns the value in the current thread's copy of this * thread-local variable. * * @return the current thread's value of this thread-local */ public T get() {
参考官方文档:ThreadLocal的用法,这个类提供“thread-local”变量,这些变量与线程的局部变量不同,每个线程都保存一份改变量的副本,可以通过get或者set方法访问。 if necessary public static int get() { return threadId.get(); } } 每个线程会“隐式”包含一份thread-local 变量的副本,只要线程还处于活跃状态,就可以访问该变量;当线程停止后,如果没有其他线程持有该thread-local变量,则该变量的副本会提交给垃圾回收器。
原文链接: https://drmingdrmer.github.io/tips/#/page/rust-thread-local-drop Rust 中有2种方法声明 thread-local[2] thread_local] 按官方说法是被"translates directly to the thread_local attribute in LLVM", 线程销毁时不会调用它的drop方法, 但宏声明的thread-local Output: // foo: 0 引用链接 [1] 原文链接: https://drmingdrmer.github.io/tips/#/page/rust-thread-local-drop [2] thread-local
child thread: when a child thread is created, the child receives initial values for all inheritable thread-local Inheritable thread-local variables are used in preference to ordinary thread-local variables when the
.*; import java.util.concurrent.atomic.AtomicInteger; /** * This class provides thread-local variables * The difference between successively generated hash codes - turns * implicit sequential thread-local * * @return the initial value for this thread-local */ protected T initialValue() * * @return the current thread's value of this thread-local */ public T get() { If this thread-local variable is subsequently * {@linkplain #get read} by the current thread, its
blocks until the flag is true.See Event Objects. (6)class threading.local A class that represents thread-local Thread-local data are data whose values are thread specific. To manage thread-local data, just create an instance of local (or a subclass) and store attributes on
线程本地握手 Thread-Local Handshakes(线程本地握手)是Java中一种用于线程间通信和数据传递的机制,引入自JEP 312(JEP是Java Enhancement Proposal Thread-Local Handshakes的目标是通过提供一种轻量级的、低开销的机制来改善这种情况。 如何使用: Thread-Local Handshakes 是通过 HotSpot 虚拟机的 Thread 类的 handshake 方法来实现的。 性能提升: 对于一些多线程应用场景,使用 Thread-Local Handshakes 可以带来性能上的提升,特别是在大量线程竞争本地数据的情况下。 在使用 Thread-Local Handshakes 时,建议仔细评估应用程序的特定需求,以确保它是适合的。此外,如同其他并发机制一样,确保代码正确同步以避免潜在的并发问题。
1、ThrealLocal 的 set() 方法 /** * Sets the current thread's copy of this thread-local variable * to the * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread /** * Returns the current thread's "initial value" for this * thread-local variable. * *
This implementation simply returns null; if the * programmer desires thread-local * * @return the initial value for this thread-local */ protected T initialValue(
先看一下源码里的解释 This class provides thread-local variables. 该码非极端情况下与某个整数取模后不容易冲突(这句话有点迷吧,其实我也不懂) 然后看一下set方法 /** * Sets the current thread's copy of this thread-local get方法我们还是要贴出来的,毕竟是我们主要分析的东西 /** * Returns the value in the current thread's copy of this * thread-local * * @return the current thread's value of this thread-local */ public T get() {
他们是ThreadLocal的神奇魔法之关键~ 接下来我们来看看ThreadLocal的关键方法: /** * Sets the current thread's copy of this thread-local ThreadLocalMap(this, firstValue); } /** * Returns the value in the current thread's copy of this * thread-local * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread getMap(Thread t) { return t.threadLocals; } /** * Removes the current thread's value for this thread-local If this thread-local variable is subsequently * {@linkplain #get read} by the current thread, its value
Dynamic (GD),Local Dynamic (LD),Initial Executable (IE),Local Executable (LE),关于这4种模型的说明参见下面oracle的文章 Thread-Local thread变量 2.静态库编译使用了-fPIC选项 3.eclipse调试跟踪静态库的代码 参考资料 《3.16 Options for Code Generation Conventions》 《Thread-Local Storage Access Models》 《Thread-local storage》
child thread: when a child thread is created, the * child receives initial values for all inheritable thread-local * *
Inheritable thread-local variables are used in preference to * ordinary thread-local variables <T> extends ThreadLocal<T> { /** * Computes the child's initial value for this inheritable thread-local
get()方法 /** * Returns the value in the current thread's copy of this * thread-local variable. * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread set()方法 /** * Sets the current thread's copy of this thread-local variable * to the specified value remove()方法 /** * Removes the current thread's value for this thread-local * variable. If this thread-local variable is subsequently * {@linkplain #get read} by the current thread, its value
threadLocal2.get()); } } 输出 hello, main hello, main2 源码分析 ThreadLocal 类上的注释: This class provides thread-local return threadId.get(); } } Each thread holds an implicit reference to its copy of a thread-local is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local
java.lang 类 ThreadLocal<T> 我们可以称ThreadLocal为:线程本地变量 官方API是这样介绍的: 该类提供了线程局部 (thread-local) 变量。 ThreadLocal类源码: get()与set()方法: /** * Returns the value in the current thread's copy of this * thread-local * * @return the current thread's value of this thread-local */ public T get() { } return setInitialValue(); } /** * Sets the current thread's copy of this thread-local
withInitial、setInitialValue、remove: /** * Returns the current thread's "initial value" for this * thread-local by {@link #get}. * *
This implementation simply returns {@code null}; if the * programmer desires thread-local Typically, an * anonymous inner class will be used. * * @return the initial value for this thread-local map.set(this, value); else createMap(t, value); } /** * Removes the current thread's value for this thread-local If this thread-local variable is subsequently * {@linkplain #get read} by the current thread, its value
Health.down(); } return status .withDetail("chance", chance) .withDetail("strategy", "thread-local <String, Object> details = new HashMap<>(); details.put("chance", chance); details.put("strategy", "thread-local 我们可能会看到类似以下内容: { "status": "DOWN", "details": { "chance": 0.9883560157173152, "strategy": "thread-local random")) .andExpect(jsonPath("$.status").exists()) .andExpect(jsonPath("$.details.strategy").value("thread-local "error": "java.lang.RuntimeException: Bad Luck", "chance": 0.9603739107139401, "strategy": "thread-local
这是也是 ThreadLocal 命名的由来 既然每个 Thread 有自己的实例副本,且其它 Thread 不可访问,那就不存在多线程间共享的问题 This class provides thread-local Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local