import java.lang.ThreadLocal.ThreadLocalMap; import java.lang.ThreadLocal.ThreadLocalMap.Entry; import java.util.HashMap; public class ThreadLocalTest2 { public ThreadLocalTest2() { super(); } /** * @param args */ public static void main(String[] args) { ThreadLocal<String> t_get = Threadlocal1(); ThreadLocal<String> tl2 = new ThreadLocal<String>(); /* * ThreadLocal是用自己的object作为map的key */ System.out.println(tl2.get()); // null System.out.println(t_get.get());// defg // ======================================= for (int i = 0; i < 3; i++) { new Thread() { public void run() { ThreadLocalManager.init(); try { /* * 保证3个线程init都执行完毕,在打出内容,发现hashMap中内容一致(被覆盖了!) */ Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(ThreadLocalManager.threadLocal1.get()); System.out.println(ThreadLocalManager.threadLocal2.get()); System.out.println(ThreadLocalManager.hm.get("key")); System.out.println("============"); } }.start(); } } public static ThreadLocal<String> Threadlocal1() { ThreadLocal<String> tl1 = new ThreadLocal<String>(); tl1.set("abc"); ThreadLocal<String> tl2 = new ThreadLocal<String>(); tl2.set("defg"); return tl2; } } class ThreadLocalManager { public static int i = 0; public static ThreadLocal<Integer> threadLocal1 = new ThreadLocal<Integer>(); public static ThreadLocal<Integer> threadLocal2 = new ThreadLocal<Integer>(); public static HashMap hm = new HashMap(); public static void init() { threadLocal1.set(Thread.currentThread().hashCode()); /* * i++,相当于new Integer(i++); * 也就是说对象已经变了,每次传过去的堆上的Integer已经变了 * 变的是引用变量的指向(static i) * 在线程内部调用了这个init()方法,相当于在每个线程都new Integer() */ threadLocal2.set(i++); /* * 这个key在hash以后在每个线程都是一样的 * threadLocal中的map的key是线程 ,每个线程不同的 */ hm.put("key", i++); } } /*getMap & createMap都是根据t : 当前 Thread作为参数,也就是说对于不同线程来说,这个ThreadLocalMap 是不同的 static class ThreadLocalMap 是一个内部类,类似map,有一个Entry[] table构成,但是没有实现Map接口*/ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } /* * createMap的时候,都是new一个对象ThreadLocalMap,然后把这个对象给t.threadLocals,t是当前线程(参看set方法) * 因为是new 的对象,所以显然证明这个ThreadLocalMap对于每一个Thread是不同的. */ void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } /* * ThreadLocalMap的构造函数传的是this - 也就是ThreadLocal对象. * hash以后,用threadlocal作为key存放我们的value, Entry 数组是典型的map实现 */ ThreadLocalMap(ThreadLocal firstKey, Object firstValue) { table = new Entry[INITIAL_CAPACITY]; int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); table[i] = new Entry(firstKey, firstValue); size = 1; setThreshold(INITIAL_CAPACITY); } /* * get方法,注意的是 if (null = map) setInitialValue * 也就是说这个ThreadLocalMap不是我们new ThreadLocal就有个,而是调用get(),set()方法的时候才会建立的 * setInitialValue 返回 null ! */ 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(); }