TreadLocal用法和实现原理

xiaoxiao2021-02-28  45

import java.util.HashMap;

public class TreadLocalTest {

    static ThreadLocal<HashMap> map0 = new ThreadLocal<HashMap>(){          @Override          protected HashMap initialValue() {              System.out.println(Thread.currentThread().getName()+"initialValue");              return new HashMap();          }      };      public void run(){          Thread[] runs = new Thread[3];          for(int i=0;i<runs.length;i++){              runs[i]=new Thread(new T1(i));          }          for(int i=0;i<runs.length;i++){              runs[i].start();          }      }      public static class T1 implements Runnable{          int id;          public T1(int id0){              id = id0;          }          public void run() {              System.out.println(Thread.currentThread().getName()+":start");              HashMap map = map0.get();              for(int i=0;i<10;i++){                  map.put(i, i+id*100);                  try{                      Thread.sleep(100);                  }catch(Exception ex){                  }              }              System.out.println(Thread.currentThread().getName()+':'+map);          }      }      /**       * Main       * @param args       */      public static void main(String[] args){          TreadLocalTest test = new TreadLocalTest();          test.run();      }

}

输出解释;

Thread-1:start  Thread-2:start  Thread-0:start  Thread-2initialValue  Thread-1initialValue  Thread-0initialValue  Thread-1:{0=100, 1=101, 2=102, 3=103, 4=104, 5=105, 6=106, 7=107, 8=108, 9=109}  Thread-2:{0=200, 1=201, 2=202, 3=203, 4=204, 5=205, 6=206, 7=207, 8=208, 9=209}  Thread-0:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}

可以看到map0 虽然是个静态变量,但是initialValue被调用了三次,通过debug发现,initialValue是从map0.get处发起的。而且每个线程都有自己的map,虽然他们同时执行。

进入Theadlocal代码,可以发现如下的片段;

public T get() {          Thread t = Thread.currentThread();          ThreadLocalMap map = getMap(t);          if (map != null) {              ThreadLocalMap.Entry e = map.getEntry(this);              if (e != null)                  return (T)e.value;          }          return setInitialValue();      }

这说明ThreadLocal确实只有一个变量,但是它内部包含一个map,针对每个thread保留一个entry,如果对应的thread不存在则会调用initialValue。

转载请注明原文地址: https://www.6miu.com/read-37184.html

最新回复(0)