ThreadLocal类学习笔记
这个类在java1.2中就出现了,线程独有的变量(每个线程都有一份变量),使用它的好处之一就是可以少传许多参数。
在哪里用到它呢?有连接池的地方就有它的身影,连接池包括数据库连接池,网络连接池等。
import java.util.UUID; class Factory { static ThreadLocal<String> connection=new ThreadLocal<>(); static String getConnection() { String s=connection.get(); if (s == null) { connection.set(UUID.randomUUID().toString()); } return connection.get(); } } public class TestThreadLocal { static void f() { String s = Factory.getConnection(); System.out.println("f :" + s); g(); } static void g() { String s = Factory.getConnection(); System.out.println("g :" + s); } public static void main(String[] args) { new Thread(() -> f()).start(); new Thread(() -> f()).start(); } }
输出结果:
f :6c71fba2-8fd6-4de9-88f9-69023290e213
f :c315c241-b379-446d-8159-dc758f020a80
g :c315c241-b379-446d-8159-dc758f020a80
g :6c71fba2-8fd6-4de9-88f9-69023290e213
ThreadLocal<String>connection这个变量其实就是一个马甲,它是唯一的一份(因为它是静态的呀)。这唯一的一份就相当于一个线程大管家,它负责去访问当前线程。请看ThreadLocal#get方法
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
第一步,它会去获取当前线程t
第二步,通过当前线程t获取ThreadLocalMap对象map
第三步,如果没有map,那就给当前线程new出来一个并赋上初值(通过setInitialValue来实现);如果已经存在,那就读取之。
ThreadLocalMap这个类是一个内部静态类,全名是:ThreadLocal.ThreadLocalMap,其内部元素的键就是this(也就是ThreadLocal实例,即上例中的connection变量),值是Object类型的实例。
Entry(ThreadLocal<?> k, Object v)
Thread这个类大名鼎鼎,它内部有一个成员变量:
ThreadLocal.ThreadLocalMap threadLocals = null;
上例中,线程1和线程2各有一份ThreadLocalMap成员变量threadLocals,这两个threadLocals中都有同一份键:connection,但是它们的值不是同一份。
每一个线程都维持一份ThreadLocalMap threadLocals,ThreadLocal这个大管家负责访问当前线程对象的threadLocals变量
可见,ThreadLocal机制是纯java代码,没有底层实现,我们自己也是可以实现的,这是一种巧妙地机制。
ThreadLocal和ThreadLocalMap在同一个文件里面并且ThreadLocalMap是ThreadLocal的静态内部类,然后Thread又有ThreadLocalMap的成员变量,最后ThreadLocal变量作为一个大管家去访问ThreadLocalMap。这个API设计的真是合理,就该这么整啊!实现起来简简单单,却带来许多便利。
ThreadLocal类学习笔记的更多相关文章
- System类学习笔记
最近在学习源码的过程中发现:很多深层次的代码都用到了一个类System类,所以决定对System类一探究竟 本文先对System类进行了剖析,然后对System类做了总结 一.首先对该类的中的所有字段 ...
- zt C++ list 类学习笔记
C++ list 类学习笔记 分类: C++ 2011-09-29 00:12 7819人阅读 评论(0) 收藏 举报 listc++iteratorvectorcconstructor 双向循环链表 ...
- GUI学习之五——QAbstractButton类学习笔记
今天总结一下AbstractButton类的学习笔记. 一.描述 AbstractButton是对各种按键的抽象类他的继承关系是这样的 首先,QAbstractButton继承了QWidget类的各种 ...
- java.util.Properties类 学习笔记
学习目标: 1.认识properties文件,理解其含义,会正确创建properties文件. 2.会使用java.util.Properties类来操作properties文件. 3.掌握相对路 ...
- Java ThreadLocal类学习
ThreadLocal为线程局部变量,通过线程名(key)-对象(value)的Map来获取每个线程对应的对象.我们不能通过ThreadLocal处理多线程并发问题,但是每个线程可以通过ThreadL ...
- PHP-解析验证码类--学习笔记
1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1 定义变量 //随机因子 private $char ...
- C++ list 类学习笔记
双向循环链表list list是双向循环链表,,每一个元素都知道前面一个元素和后面一个元素.在STL中,list和vector一样,是两个常被使用的容器.和vector不一样的是,list不支持对元素 ...
- 转载:C++ vector 类学习笔记
声明:本文转载自http://blog.csdn.net/whz_zb/article/details/6827999 vector简介 vector是STL中最常见的容器,它是一种顺序容器,支持随机 ...
- 转载:C++ list 类学习笔记
声明:本文转自http://blog.csdn.net/whz_zb/article/details/6831817 双向循环链表list list是双向循环链表,,每一个元素都知道前面一个元素和后面 ...
随机推荐
- 地图编辑器V1
功能:1. 拖放地图元素至地图编辑器中2. 可设置参考图3. 背景图可平铺,中央,左上角等放置4. 地图上的元素可旋转,可删除,可拖动5. 保存地图数据时同时生成XML格式的地图信息 -------- ...
- ELF Format 笔记(二)—— ELF Header
ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 以 32 位的 ELF header 数据结构为例: #define EI_NIDENT 16 typede ...
- ELF Format 笔记(六)—— 字符串表
ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 字符串表中包含若干以 null 结尾的字符串,这些字符串通常是 symbol 或 section 的名字.当 ...
- 欲哭无泪的@Autowired注入对象为NULL
欲哭无泪啊...一下午的时间就这么被浪费了...一个基于spring mvc和spring data jpa的小项目,当我写完一个controller的测试用例后,一运行却报空指针,跟了下是一个dao ...
- TFS代码变更和工作项关联,为系统变更提供完美的跟踪轨迹
TFS是微软的应用软件生命周期管理(ALM)的解决方案产品,相比我们常见的一些ALM产品,例如HP ALM, IBM Rational, Atlanssian Jira等,其最大的区别在于TFS将软件 ...
- Google Cloud Platform
一个离我们很遥远,很遥远的公司.作为全球三大公有云厂商之一,在国内根本听不到他的声音.其实吧,听到了也没用,因为在国内没法用!AWS还在纠结的落地过程中挣扎,GCP基本上就当不存在吧. 抛开这些乌烟瘴 ...
- MySQL Database on Azure 参数设置
在使用MySQL过程中,经常会根据需要对MySQL的参数进行一些设置和调整.作为PaaS版本的MySQL,MySQL Database on Azure在参数设置方面有一些限制,客户不能像使用on-p ...
- POJ 1556 The Doors【最短路+线段相交】
思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...
- android studio 应用小知识总结
1.在复制一个工程文件后 想修改包名,则在Android下的java中的 Android test中,鼠标右键Refactor->rename->Rename_package->Do ...
- 创建简单的机器人模型smartcar
前面我们使用的是已有的机器人模型进行仿真,这一节我们将建立一个简单的智能车机器人 smartcar,为后面建立复杂机器人打下基础. 一.创建硬件描述包. cd ~/catkin_ws/srcroscr ...