Listing4-3展示了如何使用ThreadLocal去连接两个线程的不同用户IDs
package com.owen.thread.chapter4; public class ThreadLocalDemo { private static volatile ThreadLocal<String> userID = new ThreadLocal<String>(); public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); if (name.equals("A")) userID.set("foxtrot"); else userID.set("charlie"); System.out.println(name + " " + userID.get()); } }; Thread thdA = new Thread(r); thdA.setName("A"); Thread thdB = new Thread(r); thdB.setName("B"); thdA.start(); thdB.start(); } } 之后实例化ThreadLocal和定义一个引用volatile的全局类命名为userID(这个全局是一个volatile因为它需要通过不同的线程,它可能在多处理器或多核机器上运行——用它代替final),默认主线程创建两个或多线程,它存储不同的java.lang.String.object在userID中,和输出它们的对象。 执行上面的代码,你将会看到: A foxtrot B charlie 值存储在线程局部变量中,而这些值之间没有联系。当一个新的线程被创建,它获取一个新的存储槽包含initialValue()的值。可能你需要涉及来自一个父线程(a parent thread)的值,一个线程创建另一个线程,给一个子线程,这个线程是创建过的。你可以用InheritableThreadLocal来完成任务。 InheritableThreadLocal是ThreadLocal的一个子类。下面也就是我们所知道的InheritableThreadLocal的构造器: (1)T childValue(T parentValue):计算子类的初始值作为一个父值的应用,这个时候子线程被创建。在子线程被创建之前这个方法从父线程中请求。这个方法从parentValue中返回参数,和当其它值被要求时这个方法需要重写。 Listing4-4展示如何运用InheritableThreadLocal通过父线程的Integer对象给子线程。 Listing4-4通过父线程的对象给一个子线程。 package com.owen.thread.chapter4; public class InheritableThreadLocalDemo { private static final InheritableThreadLocal<Integer> intVal = new InheritableThreadLocal<Integer>(); public static void main(String[] args) { Runnable rP = () -> { intVal.set(new Integer(10)); Runnable rC = () -> { Thread thd = Thread.currentThread(); String name = thd.getName(); System.out.printf("%s %d%n", name, intVal.get()); }; Thread thdChild = new Thread(rC); thdChild.setName("Child"); thdChild.start(); }; new Thread(rP).start(); } } 之后初始化InheritableThreadLocal和定义它为final类的变量(也可以用volatile替代)命名为intVal,这个默认线程创建一个父线程,它存储一个java.lang.Integer对象包含值为10在intVal变量中。这个父线程创建一个子线程,它调用intVal和接收它的父线程的Integer对象。执行上面代码你将会看到:Child 10。 源码下载:git@github.com:owenwilliam/Thread.git