ThreadLocal

来源:互联网 发布:美国gdp数据公布网站 编辑:程序博客网 时间:2024/06/13 02:51

1.主要作用

每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子可以存储每个线程的私有数据

ThreadLocal类提供的几个方法

⑴public T get() { }⑵public void set(T value) { }⑶public void remove() { }⑷protected T initialValue() { }   initialValue()是一个protected方法,一般是用来在使用时进行重写的,否则需要先set再get
内部原理:

ThreadLocal类中有一个静态内部类ThreadLocalMap(其类似于Map),用键值对的形式存储每一个线程的变量副本,

ThreadLocalMap中元素的key为当前ThreadLocal对象,而value对应线程的变量副本,每个线程可能存在多个ThreadLocal。

2.ThreadLocal使用

因为在上面的代码分析过程中,我们发现如果没有先set的话,即在map中查找不到对应的存储,则会通过调用setInitialValue方法返回i,
而在setInitialValue方法中,有一个语句是T value = initialValue(), 而默认情况下,initialValue方法返回的是null。

⑴例子1

public class MyThreadLocal {     //定义了一个ThreadLocal变量,用来保存int或Integer数据     private ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {         @Override        protected Integer initialValue() {             return 0;         }     };      public Integer getNextNum() {         //将tl的值获取后加1,并更新设置t1的值         tl.set(tl.get() + 1);         return tl.get();     } }
public class TestThread extends Thread {     private MyThreadLocal tlt = new MyThreadLocal();      public TestThread(MyThreadLocal tlt) {         this.tlt = tlt;     }      @Override    public void run() {         for (int i = 0; i < 3; i++) {             System.out.println(Thread.currentThread().getName() + "\t" + tlt.getNextNum());         }     } }
public class Test {     public static void main(String[] args) {         MyThreadLocal tlt = new MyThreadLocal();         Thread t1 = new TestThread(tlt);         Thread t2 = new TestThread(tlt);         Thread t3 = new TestThread(tlt);         Thread t4 = new TestThread(tlt);         t1.start();         t2.start();         t3.start();         t4.start();      } }
输出:四个线程互相不影响

Thread-0 1 Thread-1 1 Thread-0 2 Thread-1 2 Thread-0 3 Thread-1 3 Thread-2 1 Thread-3 1 Thread-2 2 Thread-3 2 Thread-2 3 Thread-3 3 
3.InheritableThreadLocal 使用
InheritableThreadLocal可以让子线程从父线程取得值,也可以进行更改,但是需要注意:当子线程取得值的同时,主线程将

InheritableThreadLocal中的值进行更改,那么子线程取到的值还是旧值。

package Thread14;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) {              // TODO Auto-generated catch block              e.printStackTrace();          }      }  }
package Thread14;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 + " 我在子线程加的~!";      } }
package Thread14;public class Tools {    public static InheritableThreadLocalExt tl = new InheritableThreadLocalExt();  }
package Thread14;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();          }      }  }
输出:

       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745       在Main线程中取值=1507176008745在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!





















0 0
原创粉丝点击