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

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

一、ThreadLocal定义

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

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

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

二、使用案例

此处使用一个案例进一步阐述该类的使用。在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开发工具下载地址及安装教程大全,点这里

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

原文地址:https://www.cnblogs.com/darendu/p/11043658.html

时间: 2024-08-29 15:48:06

ThreadLocal定义、使用案例及源码分析的相关文章

lesson1:threadlocal的使用demo及源码分析

本文中所使用的demo源码地址:https://github.com/mantuliu/javaAdvance 其中的类Lesson1ThreadLocal 本文为java晋级系列的第一讲,后续会陆续推出java相关的高级应用和分析.我个人一直都比较推崇threadlocal的设计原理和实现方式.以下关于threadlocal的描述来源于百度百科: ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”.其实,ThreadLocal并不是一个Thread,而是Thread的局部

ThreadLocal 工作原理、部分源码分析

1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap threadLocals = null; ThreadLocalMap 静态内部类维护了一个Entry 数组 private Entry[] table; 查看Entry 源码,它维护了两个属性,ThreadLocal 对象 与一个Object static class Entry extends W

【JAVA集合】HashMap源码分析(转载)

原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储的对象是一个键值对对象(Entry<K,V>): HashMap补充说明 基于数组和链表实现,内部维护着一个数组table,该数组保存着每个链表的表头结点:查找时,先通过hash函数计算hash值,再根据hash值计算数组索引,然后根据索引找到链表表头结点,然后遍历查找该链表: HashMap数据

ABP源码分析四十一:ZERO的Audit,Setting,Background Job

AuditLog: 继承自Entity<long>的实体类.封装AuditLog的信息. AuditingStore: 实现了IAuditingStore接口,实现了将AuditLog的信息保存到数据库的功能.其通过IRepository<AuditLog, long>实例完成对数据库的操作. BackgroundJobStore :  实现了IBackgroundJobStore接口,通过IRepository<BackgroundJobInfo, long>完成对B

ThreadLocal 源码分析

1.个人总结和想法: (1).ThreadLocal的内存泄漏问题? ThreadLocal 我们应该关注它的内存泄漏问题,原因虽然JDK开发者已经使用了弱引用的键来尝试解决这个问题,不过是依然存在很大风险的,因为当使用static的ThreadLocal时会使其生命周期和类一样,这样是没有必要的,就造成了内存泄漏,还有我们使用完了没有及时的清除ThreadLocal也会导致内存泄漏,内存泄漏就是让本应该被回收的对象还依然占用着内存. (2)ThreadLocal中的对象关系? ThreadLo

并发编程(四):ThreadLocal从源码分析总结到内存泄漏

一.目录 1.ThreadLocal是什么?有什么用? 2.ThreadLocal源码简要总结? 3.ThreadLocal为什么会导致内存泄漏? 二.ThreadLocal是什么?有什么用? 引入话题:在并发条件下,如何正确获得共享数据?举例:假设有多个用户需要获取用户信息,一个线程对应一个用户.在mybatis中,session用于操作数据库,那么设置.获取操作分别是session.set().session.get(),如何保证每个线程都能正确操作达到想要的结果? /** * 回顾sync

Linux内核导出符号宏定义EXPORT_SYMBOL的源码分析

源代码: <include/linux/moudule.h> --. #ifndef MODULE_SYMBOL_PREFIX #define MODULE_SYMBOL_PREFIX "" #endif --. struct kernel_symbol       //内核符号结构 { unsignedlong value;  //该符号在内存地址中的地址 constchar *name;     //该符号的名称 }; -- #define __EXPORT_SYMBO

Java中线程局部变量ThreadLocal使用教程及源码分析

在Java多线程编程中有时候会遇见线程本地局部变量ThreadLocal这个类,下面就来讲讲ThreadLocal的使用及源码分析. ThreadLocal 是Thread Local Varial(线程局部变量)的意思,每个线程在使用线程局部变量的时候都会为使用这个线程局部变量的线程提供一个线程局部变量的副本,使得每个线程都可以完全独立地操作这个线程局部变量,而不会与其他线程发生冲突,从线程的角度来看,每个线程都好像独立地拥有了这个线程局部变量.这样,看似每个线程都在并发访问同一个资源(线程局

ThreadLocal介绍以及源码分析

ThreadLocal 线程主变量 前面部分引用其他优秀博客,后面源码自己分析的,如有冒犯请私聊我. 用Java语言开发的同学对 ThreadLocal 应该都不会陌生,这个类的使用场景很多,特别是在一些框架中经常用到,比如数据库事务操作,还有MVC框架中数据跨层传递.这里我们简要探讨下 ThreadLocal 的内部实现及可能存在的问题. 首先问自己一个问题,让自己实现一个这个的功能类的话怎么去做?第一反应就是简单构造一个 Map<Thread, T> 数据结构,key是 Thread,va