所有線程共享一個變量,可以使用,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(); } } }
執行結果: