通过构造函数或方法传参
public class Worker implements Runnable { private final String message; 从主线程传入的变量 public Worker(String message) { this.message = message; } @Override public void run() { System.out.println("子线程收到: " + message); } } 主线程 public class Main { public static void main(String[] args) { String data = "Hello from main"; Thread t = new Thread(new Worker(data)); t.start(); } }通过共享对象
主线程和子线程共同访问同一个对象实例,通过该对象传递或修改数据。需要额外处理可见性和原子性(如使用 volatile、锁或原子类)。
class SharedData { volatile String message; 保证可见性 } SharedData shared = new SharedData(); shared.message = "Hello"; new Thread(() -> { while (shared.message == null) { System.out.println("等待主线程修改shared.message"); } System.out.println(shared.message); }).start();通过消息队列 / 阻塞队列
使用BlockingQueue可以在线程间安全地传递数据,尤其适用于生产者-消费者模式。
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10); 主线程放入数据 queue.put("Hello"); 子线程取出数据 Thread t = new Thread(() -> { try { String msg = queue.take(); System.out.println("子线程收到: " + msg); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); t.start();使用 InheritableThreadLocal 自动传递上下文
如果希望主线程的某些上下文(如用户会话、事务ID)自动传递给所有子线程,可以使用InheritableThreadLocal。子线程创建时会继承父线程的InheritableThreadLocal值。
public class InheritableThreadLocalTest { private static final ThreadLocal<String> threadLocal = new ThreadLocal<>(); private static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>(); public static void main(String[] args) { 父线程设置值 threadLocal.set("我是父线程threadLocal的值"); inheritableThreadLocal.set("我是父线程inheritableThreadLocal的值"); 创建并启动子线程 new Thread(() -> { 子线程中,threadLocal的值为null,inheritableThreadLocal的值则可以获取到 System.out.println("从子线程获取到threadLocal的值: " + threadLocal.get()); System.out.println("从子线程获取到inheritableThreadLocal的值: " + inheritableThreadLocal.get()); }).start(); } } 输出结果: 从子线程获取到threadLocal的值:null 从子线程获取到inheritableThreadLocal的值:我是父线程inheritableThreadLocal的值产生问题:
- 父子线程各自持有一个不同的 ThreadLocalMap 实例(容器不同),但是InheritableThreadLocal (key),以及值都作为浅拷贝存入子Map,如果你想实现真·独立副本,只需重写 childValue 方法进行深拷贝
static InheritableThreadLocal<List<String>> deepCopyItl = new InheritableThreadLocal<>() { @Override protected List<String> childValue(List<String> parentValue) { 返回一个全新的 ArrayList,切断引用联系 return parentValue == null ? null : new ArrayList<>(parentValue); } };- 拷贝逻辑只执行在线程构造方法;线程池、@Async 线程长期复用,不会重复拷贝,导致上下文失效、出现脏数据,生产不推荐,可采用阿里的TTL解决
TransmittableThreadLocal (阿里 TTL)
核心原理:在异步任务提交时刻主动捕获主线程上下文,任务执行时绑定到复用线程,执行完毕自动清理。
优势:完美兼容线程池、@Async、CompletableFuture 所有异步场景;无需手动传参,是企业级上下文传递标准方案。