1. 类ThreadLocal的使用
变量值的共享可以使用public static
变量的形式,所有的线程都使用同一个public static
变量。如果想实现每一个线程都有自己的共享变量该如何解决呢?JDK中提供的类ThreadLocal
正是为了解决这样的问题。
类ThreadLocal
主要解决的就是每个线程绑定自己的值,可以将ThreadLocal
类比喻成全局存放数据的盒子,盒子中可以存储每个线程的私有数据。
2. 解决get()返回null问题
1 2 3 4 5 6 7
| package ext; public class ThreadLocalExt extends ThreadLocal { @Override protected Object initialValue() { return "我是默认值 第一次get不再为null"; } }
|
覆盖initialValue()方法具有初始值。
3. 类InheritableThreadLocal的使用
使用类InheritableThreadLocal
可以在子线程中取得父线程继承下来的值。
3.1 值继承
使用InheritableThreadLocal类可以让子线程从父线程中取得值。
1 2 3 4 5 6 7 8
| package ext; import java.util.Date; public class InheritableThreadLocalExt extends InheritableThreadLocal { @Override protected Object initialValue() { return new Date().getTime(); } }
|
类Tools.java代码如下:
1 2 3 4 5
| package tools; import ext.InheritableThreadLocalExt; public class Tools { public static InheritableThreadLocalExt tl = new InheritableThreadLocalExt(); }
|
类ThreadA.java代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package extthread; import tools.Tools; public class ThreadA extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { System.out.println("在ThreadA线程中取值=" + Tools.tl.get()); Thread.sleep(100); } } catch (InterruptedException e) { e.printStackTrace(); } } }
|
类Run.java代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package test; import tools.Tools; import extthread.ThreadA; public class Run { public static void main(String[] args) { try { for (int i = 0; i < 10; i++) { System.out.println(" 在Main线程中取值=" + Tools.tl.get()); Thread.sleep(100); } Thread.sleep(5000); ThreadA a = new ThreadA(); a.start(); } catch (InterruptedException e) { e.printStackTrace(); } } }
|
程序运行结果如图3-64所示。

3.2 值继承再修改
如果在继承的同时还可以对值进行进一步的处理那就更好了。
1 2 3 4 5 6 7 8 9 10 11 12
| package ext; import java.util.Date; public class InheritableThreadLocalExt extends InheritableThreadLocal { @Override protected Object initialValue() { return new Date().getTime(); } @Override protected Object childValue(Object parentValue) { return parentValue + " 我在子线程加的~!"; } }
|
程序运行后的效果如图3-65所示。

但在使用InheritableThreadLocal类需要注意一点的是,如果子线程在取得值的同时,主线程将InheritableThreadLocal中的值进行更改,那么子线程取到的值还是旧值。