1、get()方法
(1)获取当前用的线程,并找到线程关联的threadLocalMap
(2)threadLocalMap为空则进行初始化一个新的并返回
(3)threadLocalMap不为空则根据threadlocal作为key查找Entry
(4)若Entry不为空则返回entry对应的值,否则执行第二条
publicTget(){ //获取当前线程 Threadt=Thread.currentThread(); ThreadLocalMapmap=getMap(t); //若当前线程关联的ThreadLocal不为空则查询 if(map!=null){ //根据threadLocal查询对应的Entry ThreadLocalMap.Entrye=map.getEntry(this); if(e!=null){ @SuppressWarnings("unchecked") Tresult=(T)e.value; returnresult; } } returnsetInitialValue(); } privateTsetInitialValue(){ //默认返回null值 Tvalue=initialValue(); Threadt=Thread.currentThread(); ThreadLocalMapmap=getMap(t); //如果当前调用线程关联的ThreadLocalMap为空则创建,否则设置值进去 if(map!=null) map.set(this,value); else //newThreadLocalMap(this,value) createMap(t,value); returnvalue; } privateEntrygetEntry(ThreadLocal<?>key){ //根据key获取其在数组的下标位置 inti=key.threadLocalHashCode&(table.length-1); Entrye=table[i]; if(e!=null&&e.get()==key) returne; else returngetEntryAfterMiss(key,i,e); } privateEntrygetEntryAfterMiss(ThreadLocal<?>key,inti,Entrye){ Entry[]tab=table; intlen=tab.length; //数组下标的Entry不为空且关联的threadlocal与查找的threadlocal不一致 while(e!=null){ ThreadLocal<?>k=e.get(); //entry关联的threadlocal与查找的相等则直接返回 if(k==key) returne; if(k==null) //关联的threadlocal为空,则触发清理key为null的Entry并重新进行rehash旧Entry数组的元素 //threadLocalMap的hash冲突与hashMap的冲突处理方式不一致,hashMap使用的是链表地址法, //而threadLocalMap使用的开放地址法——线性探测,即顺序查找下一位置或者遍历全表,效率较低 expungeStaleEntry(i); else //递增下标i的值进行下一轮的查找 i=nextIndex(i,len); e=tab[i]; } returnnull; }
2、remove()方法
(1)获取当前用的线程,并找到线程关联的threadLocalMap
(2)若不为空则删除threadLocalMap中关联的值,否则啥也不做
//ThreadLocal publicvoidremove(){ ThreadLocalMapm=getMap(Thread.currentThread()); if(m!=null) //删除当前threadLocal对象关联的Entry m.remove(this); } //ThreadLocalMap privatevoidremove(ThreadLocal<?>key){ Entry[]tab=table; intlen=tab.length; inti=key.threadLocalHashCode&(len-1); for(Entrye=tab[i]; e!=null; e=tab[i=nextIndex(i,len)]){ if(e.get()==key){ e.clear(); expungeStaleEntry(i); return; } } }
以上就是java中ThreadLocal核心方法介绍,大家会发现这些方法我们在其他的模块也有使用到。想要对其他核心方法有所了解,也可以在课后自行查阅资料。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容