类ThreadLocal的使用
变量值的共享可以使用public stati。变量的形式,所有的线程都使用同一个publicstatic变量。如果想实现每一个线程都有自己的共享变量该如何解决呢?JDK中提供的类ThreadLocal正是为了解决这样的问题。public class Run { public static ThreadLocal threadLocal = new ThreadLocal(); public static void main(String[] args) throws InterruptedException { if (threadLocal.get() == null) { System.out.println("从未放过值。"); threadLocal.set("我的值"); } System.out.println(threadLocal.get()); } }
从未放过值。 我的值 |
多个线程用一个ThreadLocal类
public class Tools { public static ThreadLocal t1 = new ThreadLocal(); }两个自定义的线程
public class MyThread1 extends Thread { public void run() { try { for (char i='a'; i<'z'; i++) { Tools.t1.set("Thread1-" + i); System.out.println("Thread1 get value=" + Tools.t1.get()); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } }
public class MyThread2 extends Thread{ public void run() { try { for (int i=0; i<30; i++) { Tools.t1.set("Thread2—" + (i+1)); System.out.println("Thread2 get value=" + Tools.t1.get()); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } }
public class Run { public static void main(String[] args) throws InterruptedException { MyThread1 a = new MyThread1(); MyThread2 b = new MyThread2(); a.start(); b.start(); for (int i=0; i<33; i++) { Tools.t1.set("Main" + (i+1)); System.out.println("Main get value=" + Tools.t1.get()); Thread.sleep(200); } } }
Main get value=Main1 Thread2 get value=Thread2—1 Thread1 get value=Thread1-a Thread1 get value=Thread1-b Thread2 get value=Thread2—2 Main get value=Main2 Thread1 get value=Thread1-c Main get value=Main3 Thread2 get value=Thread2—3 ...... |
public class ThreadLocalExt extends ThreadLocal { @Override protected Object initialValue() { return "重写ThreadLocal方法,得到初始值,让第一次get不再为null"; } }
public class Run { public static ThreadLocalExt t1 = new ThreadLocalExt(); public static void main(String[] args) throws InterruptedException { if (t1.get() == null) { System.out.println("从未放过值"); t1.set("我的值"); } System.out.println(t1.get()); } }
重写ThreadLocal方法,得到初始值,请第一次get不再为null |
public class InheritableThreadLocal<T> extends ThreadLocal<T>
使用InheritableThreadLocal类可以让子线程从父线程中取得值。
public class InheritableThreadLocalExt extends InheritableThreadLocal { @Override protected Object initialValue() { return new Date().getTime(); } }
public class Tools { public static InheritableThreadLocalExt t1 = new InheritableThreadLocalExt(); }
public class MyThread1 extends Thread { public void run() { try { for (int i=0; i<5; i++) { System.out.println("Thread1 get value=" + Tools.t1.get()); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } }
public class Run { public static void main(String[] args) throws InterruptedException { for (int i=0; i<5; i++) { System.out.println(" 在Main线程中取值=" + Tools.t1.get()); Thread.sleep(100); } Thread.sleep(3000); MyThread1 a = new MyThread1(); a.start(); } }
在Main线程中取值=1462588336441 在Main线程中取值=1462588336441 在Main线程中取值=1462588336441 在Main线程中取值=1462588336441 在Main线程中取值=1462588336441 Thread1 get value=1462588336441 Thread1 get value=1462588336441 Thread1 get value=1462588336441 Thread1 get value=1462588336441 Thread1 get value=1462588336441 |
再继承的同时还可以对值进行进一步的处理(但是在使用InheritableThreadLocal类需要注意一点的是,如果子线程在取得值 的同时,主线程将InheritableThreadLocal中的值更改,那么 子线程取到的值还是旧值)。修改如下
public class InheritableThreadLocalExt extends InheritableThreadLocal { @Override protected Object initialValue() { return new Date().getTime(); } @Override protected Object childValue(Object parentValue) { return parentValue + " 重写后在子线程加的!"; } }
在Main线程中取值=1462588868404 在Main线程中取值=1462588868404 在Main线程中取值=1462588868404 在Main线程中取值=1462588868404 在Main线程中取值=1462588868404 Thread1 get value=1462588868404 重写后在子线程加的! Thread1 get value=1462588868404 重写后在子线程加的! Thread1 get value=1462588868404 重写后在子线程加的! Thread1 get value=1462588868404 重写后在子线程加的! Thread1 get value=1462588868404 重写后在子线程加的! |