所有线程共享一个变量,可以使用,public static修饰,而如果要每个线程都有自己的共享变量,那么则可以使用ThreadLocal类来解决这个问题。
获取线程变量的方法:get();
设置线程变量的方法: set();
实例代码:
public class threadLocalTest { public static ThreadLocal t1 = new ThreadLocal(); public static void main(String[] args){ if (t1.get() == null){ t1.set("test"); } System.out.println("获取t1中的值" + t1.get()); } }
结果:
类ThreadLocal解决的是变量在不同线程间的隔离性,也就是说,不同的线程拥有自己的值,不同的线程的值可以放入ThreadLocal类中进行保存。
public class Tools { public static ThreadLocal theadLocal = new ThreadLocal(); }
public class TheadA extends Thread{ @Override public void run() { try{ for (int i = 0; i<100;i++){ Tools.theadLocal.set("TheadA" + ( i + 1 )); System.out.println("TheadA get Value=" + Tools.theadLocal.get()); Thread.sleep(2000); } }catch (InterruptedException e){ e.printStackTrace(); } } }
public class ThreadB extends Thread{ @Override public void run() { try{ for (int i = 0;i<100;i++){ Tools.theadLocal.set("ThreadB" + (i + 1)); System.out.println("ThreadB get Value=" + Tools.theadLocal.get()); TheadA.sleep(2000); } }catch (InterruptedException e){ e.printStackTrace(); } } }
public class Run { public static void main(String[] args) { try { TheadA a = new TheadA(); ThreadB b = new ThreadB(); a.start(); b.start(); for (int i=0;i<100;i++){ Tools.theadLocal.set("Main" + ( i + 1)); System.out.println("Main get value=" + Tools.theadLocal.get()); Thread.sleep(2000); } } catch (InterruptedException e) { e.printStackTrace(); } } }
执行结果:
从执行结果可以看到,3个线程都通过t1对象的set()方法设置值,但是,每个线程还是只能取出自己的数据。
ThreadLocal的默认值:
由源码可以看出,ThreadLocal的默认值是null,则如果要设置默认值,重写ThreadLocal即可。
public class ThreadLcoalExt extends ThreadLocal{ @Override protected Object initialValue() { return "此为默认值"; } }
public class ThreadLocalInitValue { public static ThreadLcoalExt t = new ThreadLcoalExt(); public static void main(String[] args){ if (t.get() == null){ System.out.println("从未放过值"); t.set("我的值"); } System.out.println(t.get()); } }
执行结果:
扩展:
类InheritableThreadLocal可以在子线程中可以取得父线程继承下来的值。
public class InheritableThreadLocalA extends TheadA { @Override public void run() { try{ for (int i=0;i<100;i++){ System.out.println("在InheritableThreadLocalA线程中取值" + InheritableThreadTools.t.get()); Thread.sleep(100); } }catch (InterruptedException e){ e.printStackTrace(); } } }
public class InheritableThreadLocalExt extends InheritableThreadLocal { @Override protected Object initialValue() { return new Date().getTime(); } }
public class InheritableThreadTools { public static InheritableThreadLocalExt t = new InheritableThreadLocalExt(); }
public class InheritableThreadRun { public static void main(String[] agrs){ try{ for (int i=0;i<100;i++) { System.out.println("在main线程中取值=" + InheritableThreadTools.t.get() ); Thread.sleep(100); InheritableThreadLocalA t = new InheritableThreadLocalA(); t.start(); } }catch (InterruptedException e){ e.printStackTrace(); } } }
执行结果: