• ThreadLocal定义、使用案例及源码分析


    原文连接:(http://www.studyshare.cn/blog/details/1165/0 )

    一、ThreadLocal定义

    jdk官方文档定义是:该类提供线程局部变量。 这些变量与其正常的对应方式不同,因为访问一个线程(通过其@code get或@code set方法)的每个线

    程都有自己的独立初始化变量副本。

    通俗来讲就是:使用ThreadLocal包装后的对象,在ThreadLocal所在线程中会有一个对象副本,该副本只会在拥有它的线程中使用,别的线程无法访问。

    java开发工具下载地址及安装教程大全,点这里
    更多深度技术文章,在这里

    二、使用案例

    此处使用一个案例进一步阐述该类的使用。在web项目中,会使用一个切点类,在一个web请求到来后,需要在服务接口的业务方法执行前后做一些工作。

    此处就做简单的工作,打印每个service方法执行前到执行完毕的所需的时间,同时把执行方法的全路径、方法名和返回结果进行打印。

    1、定义一个切点类,该类中定义两个ThreadLocal,如下图

     

    2、类中的几个关键方法定义如下

     

    分析:Web容器中,每个完整的请求周期会由一个线程来处理。那么我们在这个线程中使用ThreadLocal定义自己的线程变量副本,并使用这个副本隔离

    变量共享从而达到线程安全的目的。

    三、源码分析

    1、进入ThreadLocal源码,提供了如下几个方法

    public T get() : 该方法返回当前线程所对应的线程局部变量

    public void set(T value) : 设置当前线程的线程局部变量的值

    public void remove() : 将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该

    线程的局部变量将自动被 垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。

    protected T initialValue() { return null; } : 返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个

    延迟调用方法, 在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

    2、观察ThreadLocal的get()方法

     

    3、ThreadLocal中包含一个静态内部类ThreadLocalMap,该类中还定义了Entry静态内部类,该类的构造方法如下:

     

    可以看到有个Entry内部静态类,它继承了WeakReference,总之它记录了两个信息,一个是ThreadLocal<?>类型,一个是Object类型的值。getEntry

    方法则是获取某个ThreadLocal对应的值,set方法就是更新或赋值相应的ThreadLocal对应的值。

    回顾我们的get方法,其实就是拿到每个线程独有的ThreadLocalMap,然后再用ThreadLocal的当前实例,拿到Map中的相应的Entry,然后就可以拿

    到相应的值返回出去。当然,如果Map为空,还会先进行map的创建,初始化等工作。

    以上就是ThreadLocal的使用及源码分析,ThreadLocal在开发中要谨慎使用,因为它可能会引起内存泄露,不过它的设计中使用的弱引用(弱引用的

    生命周期是下一次GC到达即被回收),对内存泄漏进行了一层保障。

    本文为博主原创文章,转载请注明原文出处。

    java开发工具下载地址及安装教程大全,点这里

    更多深度技术文章,在这里

  • 相关阅读:
    安卓之视图View的基本属性
    安卓之颜色
    安卓之屏幕显示
    sockfd_to_family函数
    family_to_level函数
    mcast_get_ttl函数
    mcast_get_loop函数
    mcast_set_ttl函数
    mcast_set_loop函数
    20200730 尚硅谷 JVM 16
  • 原文地址:https://www.cnblogs.com/darendu/p/11043658.html
Copyright © 2020-2023  润新知