threadlocal正确使用方法,thread local通俗易懂

首页 > 技术 > 作者:YD1662023-04-15 23:31:07

这样的话,在get的时候,也会根据ThreadLocal对象的hash值,定位到table中的位置,然后判断该位置Entry对象中的key是否和get的key一致,如果不一致,就判断下一个位置,set和get如果冲突严重的话,效率还是很低的。

以下是get的源码,是不是就感觉很好懂了:

privateEntrygetEntry(ThreadLocal<?>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; //get的时候一样是根据ThreadLocal获取到table的i值,然后查找数据拿到后会对比key是否相等if(e!=null&&e.get()==key)。 while(e!=null){ ThreadLocal<?>k=e.get(); //相等就直接返回,不相等就继续查找,找到相等位置。 if(k==key) returne; if(k==null) expungeStaleEntry(i); else i=nextIndex(i,len); e=tab[i]; } returnnull; }能跟我说一下对象存放在哪里么?

在Java中,栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存,而堆内存中的对象对所有线程可见,堆内存中的对象可以被所有线程访问。

那么是不是说ThreadLocal的实例以及其值存放在栈上呢?

其实不是的,因为ThreadLocal实例实际上也是被其创建的类持有(更顶端应该是被线程持有),而ThreadLocal的值其实也是被线程实例持有,它们都是位于堆上,只是通过一些技巧将可见性修改成了线程可见。

如果我想共享线程的ThreadLocal数据怎么办?

使用InheritableThreadLocal可以实现多个线程访问ThreadLocal的值,我们在主线程中创建一个InheritableThreadLocal的实例,然后在子线程中得到这个InheritableThreadLocal实例设置的值。

privatevoidtest(){ finalThreadLocalthreadLocal=newInheritableThreadLocal(); threadLocal.set("帅得一匹"); Threadt=newThread(){ @Override publicvoidrun(){ super.run(); Log.i("张三帅么=" threadLocal.get()); } }; t.start(); }

在子线程中我是能够正常输出那一行日志的,这也是我之前面试视频提到过的父子线程数据传递的问题。

怎么传递的呀?

传递的逻辑很简单,我在开头Thread代码提到threadLocals的时候,你们再往下看看我刻意放了另外一个变量:

threadlocal正确使用方法,thread local通俗易懂(9)

Thread源码中,我们看看Thread.init初始化创建的时候做了什么:

publicclassThreadimplementsRunnable{ …… if(inheritThreadLocals&&parent.inheritableThreadLocals!=null) this.inheritableThreadLocals=ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); …… }

我就截取了部分代码,如果线程的inheritThreadLocals变量不为空,比如我们上面的例子,而且父线程的inheritThreadLocals也存在,那么我就把父线程的inheritThreadLocals给当前线程的inheritThreadLocals。

是不是很有意思?

threadlocal正确使用方法,thread local通俗易懂(10)

小伙子你懂的确实很多,那你算是一个深度的ThreadLocal用户了,你发现ThreadLocal的问题了么?

你是说内存泄露么?

,这小子为啥知道我要问什么?嗯嗯对的,你说一下。

这个问题确实会存在的,我跟大家说一下为什么,还记得我上面的代码么?

threadlocal正确使用方法,thread local通俗易懂(11)

ThreadLocal在保存的时候会把自己当做Key存在ThreadLocalMap中,正常情况应该是key和value都应该被外界强引用才对,但是现在key被设计成WeakReference弱引用了。

threadlocal正确使用方法,thread local通俗易懂(12)

上一页1234下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.