Java 多线程同步问题的探究(五、你有我有全都有—— ThreadLocal如何解决并发安全性?)
2010-05-14 00:00:00 来源:WEB开发网貌似这个程序没什么问题。但是运行结果却显示:这个程序中的3个线程会抛出3个空指针异常。读者一定感到很困惑。我明明在构造器当中把Student对象 set进了ThreadLocal里面阿,为什么run起来之后居然在调用stuLocal.get()方法的时候得到的是NULL呢?
带着这个疑问,让我们深入到JDK的代码当中,去一看究竟。
原来,在ThreadLocal中,有一个内部类叫做ThreadLocalMap。这个ThreadLocalMap并非java.util.Map的一个实现,而是利用java.lang.ref.WeakReference实现的一个键-值对应的数据结构其中,key是ThreadLocal类型,而value是Object类型,我们可以简单的视为HashMap<ThreadLocal,Object>。
而在每一个Thread对象中,都有一个ThreadLocalMap的引用,即Thread.threadLocals。而ThreadLocal的 set方法就是首先尝试从当前线程中取得ThreadLocalMap(以下简称Map)对象。如果取到的不为null,则以ThreadLocal对象自身为key,来取Map中的value。如果取不到Map对象,则首先为当前线程创建一个ThreadLocalMap,然后以ThreadLocal 对象自身为key,将传入的value放入该Map中。
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
而get方法则是首先得到当前线程的ThreadLocalMap对象,然后,根据ThreadLocal对象自身,取出相应的value。当然,如果在当前线程中取不到ThreadLocalMap对象,则尝试为当前线程创建ThreadLocalMap对象,并以ThreadLocal对象自身为 key,把initialValue()方法产生的对象作为value放入新创建的ThreadLocalMap中。
更多精彩
赞助商链接