如下是JDK1.8源碼中對ThreadLocal的官方解釋,已經很是精煉了。html
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 instances are subject to garbage collection (unless other references to these copies exist).
白話一點就是每一個thread在本身的生命週期內維護着一個本地變量,僅供自身上下文使用。java
其實JDK源碼裏已經給出了使用的樣例,這裏就當自我熟悉一下。(這個例子主要是爲了用下initialValue()
,能夠直接看第二個簡單例子)less
package cn.lw.thread; import java.util.UUID; /** * @author wanglei 2018年5月3日 */ public class ThreadLocalTest3 { public static void main(String[] args) { MyThread3 myThread = new MyThread3(); Thread t1 = new Thread(myThread, "t1"); Thread t2 = new Thread(myThread, "t2"); t1.start(); t2.start(); try { t1.join(); //等待t1終止 t2.join(); //等待t2終止 } catch (InterruptedException e) { e.printStackTrace(); } } } class MyThread3 implements Runnable { @Override public void run() { // 初始化當前thread的local-value,僅當前thread可見 ThreadLocal<String> myThreadLocal = new ThreadLocal<String>() { @Override protected String initialValue() { return UUID.randomUUID().toString(); } }; String name = Thread.currentThread().getName(); // 獲取初始值 String initialValue = myThreadLocal.get(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } // 將當前thread的local-value改成指定值 myThreadLocal.set(UUID.randomUUID().toString()); System.out.println("Thread name: " + name + ", init: " + initialValue + ", next: " + myThreadLocal.get()); } }
Output:dom
Thread name: t2, init: 26e62cc8-1457-43a2-956c-6e53f5ccadd3, next: 7d32cd8d-7143-4879-a65b-a0841d2b6e9d Thread name: t1, init: 9ab664fc-0af2-4a1d-bcd8-e4f056b6748f, next: 7a6f44dc-bd20-438e-85be-ff42ba19ad6e
這個類繼承自ThreadLocal。顧名思義,目的就是讓child-thread能夠訪問parent-thread的local-value。並且能夠經過重寫childVaule()
方法任意改變parent-thread的local-value.ide
package cn.lw.thread; import java.util.UUID; /** * @author wanglei 2018年5月3日 */ public class ThreadLocalDemo { public static void main(String[] args) { new Thread(new ParentClass("p1")).start(); new Thread(new ParentClass("p2")).start(); } } class ThreadLocalManager { // private static final ThreadLocal<String> localValue = new ThreadLocal<>(); private static final InheritableThreadLocal<String> localValue = new InheritableThreadLocal<>(); public static void setLocalValue() { localValue.set(UUID.randomUUID().toString()); } public static String getLocalValue() { return localValue.get(); } public static void removeLocalValue() { localValue.remove(); } } class ParentClass implements Runnable { private String name; public ParentClass(String name) { this.name = name; } @Override public void run() { ThreadLocalManager.setLocalValue(); System.out.println("parent name: "+name+", loval value: "+ThreadLocalManager.getLocalValue()); String childName = name + "_child"; ChildClass childClass = new ChildClass(childName); Thread childThread = new Thread(childClass); childThread.start(); try { childThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } class ChildClass implements Runnable { private String name; public ChildClass(String name) { this.name = name; } @Override public void run() { System.out.println("child name: "+name+", loval value: "+ThreadLocalManager.getLocalValue()); } }
Output:this
parent name: p2, loval value: 3a623559-9457-4cb0-8ba1-b958336a70cd parent name: p1, loval value: 48594e57-a114-43c1-980e-034074387d0a child name: p2_child, loval value: 3a623559-9457-4cb0-8ba1-b958336a70cd child name: p1_child, loval value: 48594e57-a114-43c1-980e-034074387d0a
ThreadLocal 主要源碼能夠參考這篇文章:ThreadLocal源碼解讀code