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 ...
随机推荐
- cocoapods升级
1.更新gem:sudo gem update --system 先要查看下源,如果源被墙了就换地址:https://gems.ruby-china.com 1.1.删除gem源:gem source ...
- Spring Boot Admin 详解(Spring Boot 2.0,基于 Eureka 的实现)
原文:https://blog.csdn.net/hubo_88/article/details/80671192 Spring Boot Admin 用于监控基于 Spring Boot 的应用,它 ...
- httprunner学习25-文件上传multipart/form-data
前言 httprunner上传文件接口,其实跟requests上传文件的接口是一样的,之前在python接口系列里面有案例 python接口自动化16-multipart/form-data上传图片 ...
- VS操作中遇到的问题及解决
1.无法解析的外部符号 _main,该符号在函数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) 中被引用 2. /ZI ...
- github1:workq
https://github.com/taf2/workq https://github.com/erez-strauss/lockfree_mpmc_queue 多生产者 多消费者 队列 < ...
- vs2008 vc90.pdb 不是创建此预编译头时使用的 pdb 文件,请重新创建预编译头
解决方案: 找到项目中的stdafx.cpp,右键属性,找到C/C++->预编译头, 设置为创建预编译头, 重新生成
- Django-Model操作数据库
查询 models.UserInfo.objects.all() models.UserInfo.objects.all().values('user') #只取user列 models.UserIn ...
- 5分钟使用docker搭建一个WordPress
环境为已安装Docker Destop的Windows系统. 过程 使用Docker拉去官方WordPress镜像再进行简单配置是可行的, 但是这里我们使用docker-compose,它会自动根据你 ...
- js 浮点数计算精度不准确问题
或许很多人都遇到过,js 对小数的加.减.乘.除时经常得到一些奇怪的结果! 比如 :0.1 + 0.2 = 0.3 ? 这么一个简单的计算,当你用js 计算时会发现结果是:0.30000000000 ...
- zzulioj - 2623: 小H的作业题
题目链接:http://acm.zzuli.edu.cn/problem.php?id=2623 题目描述 期末考试即将来临,同学们都积极的在图书馆复习.今天小H也来到图书馆复习,小H掏 ...