threadlocal工作原理,threadlocal的作用和实现原理

  threadlocal工作原理,threadlocal的作用和实现原理

  ThreadLocal表示线程局部变量!那么什么是线程局部变量呢?这东西有什么用?有没有面试被问到说不出一二三的?今天就来看看这款产品的源代码,从根本上了解这款产品是做什么的。

  如何解决写爬虫IP受阻的问题?立即使用。

  Thread、ThreadLocalMap、Entry三者关系

  其实他的源代码实现并没有想象中那么复杂。要点如下:

  1.Java可以通过Thread.currentThread()获取Thread的当前实例对象。既然我们可以获得Thread对象实例,我们就可以操作它,比如为Thread对象设置一个值。

  2.每个线程对象都有一个ThradLocalMap实例,它有一个条目数组。Entry对象有两个主要属性:value的弱引用和ThreadLocal,其中value属性是设置给当前线程的值,也是ThreadLocal的核心属性:

  静态类入口扩展WeakReferenceThreadLocal?{

  /**与此ThreadLocal关联的值。*/

  对象值;

  Entry(ThreadLocal?k,对象v) {

  超(k);

  值=v;

  }

  }注意Entry继承自WeakReference,其key为ThreadLocal object!(图1)

  结合1和2两个知识点,我们可以知道,我们得到thread对象后,就可以操作当前Thread对象的ThreadLocalMap对象,然后把我们要保存的值赋给ThreadLocalMap的Entry的value属性。Thread、ThreadLocalMap、value、Value之间的关系可以如下图所示(图2):

  从上图可以得出这样的结论:一个Thread对象持有一个ThreadLocalMap对象,然后,一个ThreadLoMap对象包含若干个ThreadLocal对象以及ThreadLocal对象所在线程的值!总之:一个线程对象可以保存多个ThreadLocal对象的变量值。

  那么ThreadLocal和Thread有什么关系呢?他们如何读取值?下面根据源代码做一个简单的分析。

  ThreadLocal和Thread的关联

  先看ThreadLocal的set方法:

  公共空集(T值){

  //获取当前线程

  thread t=thread . currentthread();

  //获取当前线程持有的ThreadLocalMap

  ThreadLocalThreadLocalMap map=get map(t);

  //将值设置为threadlocalMap

  如果(图!=空)

  map.set(this,value);

  其他

  createMap(t,value);

  }set方法很有逻辑,也很简单(结合上面的图2可以更好的理解J):

  1.通过currentThread方法获取currentThread对象。

  2.获取当前线程对象的ThreadLoalMap对象。

  3.用值和ThreadLocal对象形成一个Entry对象,并将其保存在

  在ThreadLoalMap的条目类型数组中。

  在来看看ThreadLocal的get方法:

  public T get() {

  //获取当前线程

  thread t=thread . currentthread();

  //获取当前线程的ThreadLocalMap对象

  ThreadLocalMap map=get map(t);

  如果(图!=null) {

  //获取要与ThreadLocal对象关联的值

  ThreadLocalMap。entry e=map . get entry(this);

  如果(e!=null) {

  @SuppressWarnings(未选中)

  //获取值

  T结果=(T)e . value;

  返回结果;

  }

  }

  //null返回初始化值

  返回setInitialValue();

  }可以开发get的整体逻辑也很简单:

  1.获取当前线程对象。

  2.获取当前线程对象的ThreadLocalMap对象

  3.从ThreadLocalMap中获取与ThreadLocal关联的Entry对象,特别是以ThreadLocal作为键。

  4.在步骤3中获取条目的value属性并返回它。

  通过整体观察get和set方法,可以得出以下结论:ThreadLocal对象调用set方法给Thread对象的ThreadLocalMap添加值;ThreadLocal对象调用get方法从thread对象的Threadlocal映射中获取值。核心是操纵Thread对象的ThreadLocalMap对象读写值。原理就是这么简单。

  那么位于不同线程中的不同ThreadLocal对象与保存其他线程中的值有什么关系呢?下图可以清晰的描述出来:

  ThreadLocal的使用实例

  现在我们知道一个线程在Android中只有一个Looper对象,那么是怎么做到的呢?有效的是ThreadLocal。看看Looper的准备方法:

  //定义静态ThreadLocal变量

  static final threadlocal looper sThreadLocal=new threadlocal looper();

  私有静态void准备(布尔quitAllowed) {

  //一个线程只能与一个Looper对象相关联。

  if (sThreadLocal.get()!=null) {

  抛出新的RuntimeException(“每个线程只能创建一个循环”);

  }

  sthreadlocal . set(new Looper(quit allowed));

  }通过观察prepare方法,可以通过sThreadLocal的get方法知道当前线程是否已经有Looper对象,如果有,抛出异常;如果当前线程没有设置Looper对象,调用ThreadLocal的set方法初始化Looper对象,并将其赋予当前线程:

  sthreadlocal . set(new Looper(quit allowed));这确保了一个线程只有一个Looper对象。

  至此,ThreadLocal的原理已经基本分析完毕。至于内部如何设置和获取,博主没有做太详细的分析,因为没必要。只要知道ThreadLocal的工作原因和使用场景就可以了。以上是ThreadLocal原理分析的详细内容。更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: