ThreadLocal的底层实现

我们都知道,ThreadLocal提供了一种将资源绑定到当前线程的手段,实现资源在线程之间的隔离。通过setget方法能够进行资源的存取操作。
从它的方法来看,仿佛ThreadLocal就是个容器,为我们保存资源,实际上是这样的吗?它到底是怎么做到线程隔离的?

问题描述

定义一个ThreadLocal对象local,线程t1和t2均会使用local.set放置资源,t1,t2在通过get获取时又只会拿到自己set进去的资源,这种线程隔离是怎么做到的?明明只有一个ThreadLocal对象为多个线程服务,但却保持了线程间的隔离

实现原理

ThreadLocal并不是个容器,它本身不会存储任何资源,如果它是一个容器,任何一个线程均能访问容器内的所有资源,无法做到线程隔离。
ThreadLocal中有个内部类ThreadLocalMap,key为ThreadLocal对象,value为资源内容。
ThreadLocalMap的实例保存在Thread中,这是线程隔离的关键,即每个Thread都会持有独属于自己的一个ThreadLocalMap,线程通过ThreadLocal.set保存的资源实际上保存在这个ThreadLocalMap中。

ThreadLocal.get

在使用ThreadLocal.get时,其执行步骤如下:

  1. ThreadLocal会获取到当前的线程thread
  2. thread中拿到这个thread独有的ThreadLocalMap
  3. ThreadLocalMap取得自己这个ThreadLocal对象对应的Entity
  4. 返回这个Entityvalue

ThreadLocal.set

在使用ThreadLocal.set时,其执行步骤如下:

  1. ThreadLocal会获取到当前的线程thread
  2. thread中拿到这个thread独有的ThreadLocalMap
  3. Map中添加key为自身ThreadLocal对象、value为资源的Entity

从上面可以看到,ThreadLocal有两个功能

  • 资源标记,ThreadLocal对象为key,资源为value,作为一个资源的标记
  • 执行者,它从线程自身中拿到对应的资源并还给线程

ThreadLocal适用场景

  1. 多线程环境下,将共享变量变成多个线程独有的副本,将共享变成不共享,解决并发问题
  2. 作为一种传递数据的手段,如果某个资源很多地方都会用到,而每次创建又很麻烦或者很占资源,可以直接放到ThreadLocal中,其他地方直接从ThreadLocal中取得即可
发布了98 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Mutou_ren/article/details/103068868
今日推荐