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开发工具下载地址及安装教程大全,点这里。
更多深度技术文章,在这里。
ThreadLocal定义、使用案例及源码分析的更多相关文章
- 并发容器之阻塞队列DelayQueue的使用案例及源码分析
原文连接:(http://www.studyshare.cn/blog-front//blog/details/1167/0 ) 一.队列及阻塞队列概念 1.队列:是一种特殊线性表,特殊之处在于操作是 ...
- Springboot基于Redisson实现Redis分布式可重入锁【案例到源码分析】
一.前言 我们在实现使用Redis实现分布式锁,最开始一般使用SET resource-name anystring NX EX max-lock-time进行加锁,使用Lua脚本保证原子性进行实现释 ...
- lesson1:threadlocal的使用demo及源码分析
本文中所使用的demo源码地址:https://github.com/mantuliu/javaAdvance 其中的类Lesson1ThreadLocal 本文为java晋级系列的第一讲,后续会陆续 ...
- ThreadLocal 工作原理、部分源码分析
1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...
- ThreadLocal 线程本地变量 及 源码分析
■ ThreadLocal 定义 ThreadLocal通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量 ...
- ABP源码分析四十一:ZERO的Audit,Setting,Background Job
AuditLog: 继承自Entity<long>的实体类.封装AuditLog的信息. AuditingStore: 实现了IAuditingStore接口,实现了将AuditLog的信 ...
- 【JAVA集合】HashMap源码分析(转载)
原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储 ...
- Java 容器源码分析之1.7HashMap
以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储的对象是一个键值对对象(Entry<K,V>): HashMap补充说明 基于数组和链表 ...
- ThreadLocal 简介 案例 源码分析 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
随机推荐
- 栈 队列 hash表 堆 算法模板和相关题目
什么是栈(Stack)? 栈(stack)是一种采用后进先出(LIFO,last in first out)策略的抽象数据结构.比如物流装车,后装的货物先卸,先转的货物后卸.栈在数据结构中的地位很重要 ...
- actuator beans不展示
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...
- 字符串format()方法的基本使用
<模板字符串>.format(<逗号分隔的参数>) 其中,模板字符串是一个由字符串和槽组成的字符串,用来控制字符串和变量的显示效果.槽用大括号({})表示,对应format() ...
- CAJViewer 去除右上角闪动的图标
打开CMD,粘贴如下代码: %homedrive% cd "%userprofile%\Documents\My eBooks\" del ad0.xml md ad0.xml m ...
- Taro-UI 2.0样式在H5上生效,微信小程序不生效?
答案: https://taro-ui.aotu.io/#/docs/questions taro-ui 自定义样式覆盖小程序组件样式使用到了 globalClass 这个微信小程序特性,由于微信小程 ...
- 12 opencv图像合成
#include < stdio.h > #include < opencv2\opencv.hpp > #include < opencv2\stitching.hpp ...
- 回溯法 | n皇后问题
今早上看了一篇英语阅读之后,莫名有些空虚寂寞冷.拿出算法书,研读回溯法.我觉得n皇后问题完全可以用暴力方式,即先对n个数进行全排列,得到所有结果的下标组合,问题规模为n!. 全排列花了比较久的时间才编 ...
- 基环树DP
基环树DP Page1:问题 啥是基环树?就是在一棵树上增加一条边. Page2:基环树的几种情况 无向 有向:基环外向树,基环内向树. Page3:处理问题的基本方式 1.断环成树 2.分别处理树和 ...
- 将float数字按照一定格式写入到文件中
/* float.c */ #include<stdio.h> #include<string.h> int main() { FILE *fp = fopen("D ...
- 远程windows
1. 起因 因为经常用teamviewer,所以断定我是商业用户,不允许我用了.想买一个授权,结果太贵了,1700多.使用了很多其他的,向日葵卡顿,有的窗口点不到,vnc慢,效果差,卡顿,还收费,等等 ...