读读ThreadLocal

前言

  • ThreadLocal给每个线程创建一个副本,方便线程存储本地数据。ThreadLocal不存在线程之间的数据传递,只会保证在同一个线程的生命周期内随时访问,存储数据。本文会介绍一下Threadlocal的使用场景,Thread和ThreadLocal之间的关系。

使用场景

  • 私有化的数据存储可以直接使用对象,但是这样需要在不同的类和方法之间传递数据存储对象。也可以使用静态化存储,但是静态存储是线程共享的,如果存储数据在线程生命周期内会有变化,那么我们还需要维护容器的线程安全,这是一笔很大的开销,没有必要的情况下,尽量不要使用。而ThreadLocal是介于二者之间的优化实践。
public class AccessContext {
    private static final ThreadLocal<String> REQUEST_IP = new ThreadLocal<>();
    public static void setRequestIp(String ip) {
        REQUEST_IP.set(ip);
    }

    public static String getRequestIp() {
        return REQUEST_IP.get();
    }

    public static void clearAll() {
        REQUEST_IP.remove();
    }
}
  • 什么情况下使用ThreadLocal?线程间共享范围太大,对象存储范围太小的时候。
  • 都说java是面向对象的编程。说下我对对象编程的理解:蚁族中有工蚁,兵蚁,蚁后等,那么对象在我看来颇有相似之处。对象有数据存储对象,功能对象,结构对象,生产对象的对象,熟悉设计模式的可能理解更加深刻一些。面向对象编程就是:创建对象,组合对象。不同属性对象组成不同功能框架,不同功能框架组成不同应用。

原理

  • 什么时候需要我们使用ThreadLocal?每个独立的java应用都是一个进程,进程中是线程的生生灭灭,而我们的代码真正生活的地方叫线程。来张图看下进程,Thread,ThreadLocal在计算机中的位置关系,很简单~


    11232151-b4c64adfe2942e9a.png
    线程本地存储
  • 很显然,Thread中有一个对象的引用,指向ThreadLocalMap,这个Map容器的定义和操作处理在ThreadLocal中定义,稍后介绍ThreadLocalMap,想一下它和普通的HashMap有什么区别?为什么不直接使用HashMap存储呢?


    11232151-ef11ebe406c0ec82.png
    image.png
  • Thread中使用threadLocalMap的情况,很显然,都在ThreadLocal中。看下它的使用情况:


    11232151-f290e2669c034797.png
    image.png
  • 在Thread中,exit()方法是系统调用,在线程真正结束之前会释放资源,反之,线程没有结束的时候ThreadLocalMap不会释放,有些时候需要手动释放。


    11232151-2f91491fd066ebef.png
    image.png
  • 上面这个方法来自ThreadLocal,从一个Thread中取出它的存储对象ThreadLocalMap。

ThreadLocalMap

  • 对象的存储结构是个永恒的话题。ThreadLocalMap是自定义的Map,不是Map的子类。这个Map是Entry组成的,看它继承了WeakReference,弱引用。


    11232151-b935451f9e753cc1.png
    image.png
  • 把对象存入Thread,使用Threadlocal.
    1.获得当前线程Thread对象;
    2.getMap(t)获得数据存储对象ThreadLocalMap;
    3.如果map是空的,初始化threadLocals,否则把数据存入map。


    11232151-dd569541736ea537.png
    image.png
11232151-0cbdbcac35a4aa43.png
image.png
  • 获得ThreadLocal中存储的对象
    1.首先获得线程对象
    2.获得数据存储对象
    3.如果Map不是null,获得Entry,entry中取到存储的数据
    4.map是null的,需要初始化


    11232151-330baf9c55c6d519.png
    image.png

    11232151-ef3dec8f2233d550.png
    image.png

猜你喜欢

转载自blog.csdn.net/weixin_33806914/article/details/86962914