java多线程-ThreadLocal
大纲:
- 用法
- 源码
一、用法
ThreadLocal是一个容器,顾名思义就是把一个变量存到线程本地。
class Test {
public static void main(String[] args) {
new Thread(new TestLocal()).start();
new Thread(new TestLocal()).start();
new Thread(new TestLocal()).start();
}
}
class TestLocal implements Runnable {
ThreadLocal<String> localName = new ThreadLocal<>();
@Override
public void run() {
localName.set(Thread.currentThread().getName());
System.out.println(localName.get());
}
}
/**结果:
* Thread-0
* Thread-1
* Thread-2
*/
二、源码
ThreadLocal是线程本地变量,因此每个Thread对象内部必然存储ThreadLocal,ThreadLocal作为key,存储在ThreadLocalMap中。
class Thread {
ThreadLocal.ThreadLocalMap threadLocals = null; //每个线程对象内部维护了一个ThreadLocal.ThreadLocalMap。
...
}
ThreadLocal主要方法就是set,get
- set:
public class ThreadLocal<T> {
static class ThreadLocalMap {...} //ThreadLocalMap是ThreadLocal的静态内部类
...
public void set(T value) {
Thread t = Thread.currentThread(); //拿到当前线程
ThreadLocalMap map = getMap(t); //取出线程维护的ThreadLocalMap
if (map != null)
map.set(this, value); //ThreadLocalMap的key为当前ThreadLocal对象,value就是我们需要存储的变量
else
createMap(t, value); //该线程第一次使用ThreadLocal.set时创建ThreadLocalMap对象,并赋值。
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
...
}
- get:
public class ThreadLocal<T> {
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t); //从当前线程取出ThreadLocalMap
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this); //以当前ThreadLocal对象为key取出ThreadLocalMap.Entry
if (e != null) {
T result = (T)e.value;
return result;
}
}
return setInitialValue(); //如果这个ThreadLocal对象没有赋值直接get,会给它赋值为null并返回。
}
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
protected T initialValue() {
return null;
}
...
}
ThreadLocal get、set思想小结:
- 拿到当前线程对象。
- 拿到线程对象内部维护的ThreadLocalMap对象。
- 一个线程对象中只有一个ThreadLocalMap对象,所有ThreadLocal对象及这个ThreadLocal对象存储的值都以key-value的形式存在ThreadLocalMap中。(ThreadLocalMap的key是ThreadLocal对象,value是需要存储的变量。)
java多线程-ThreadLocal的更多相关文章
- Java多线程——ThreadLocal类的原理和使用
Java多线程——ThreadLocal类的原理和使用 摘要:本文主要学习了ThreadLocal类的原理和使用. 概述 是什么 ThreadLocal可以用来维护一个变量,提供了一个ThreadLo ...
- [Java多线程]-ThreadLocal源码及原理的深入分析
ThreadLocal<T>类:以空间换时间提供一种多线程更快捷访问变量的方式.这种方式不存在竞争,所以也不存在并发的安全性问题. //-------------------------- ...
- Java多线程ThreadLocal介绍
在Java多线程环境下ThreadLocal就像一家银行,每个线程就是银行里面的一个客户,每个客户独有一个保险箱来存放金钱,客户之间的金钱不影响. private static ThreadLocal ...
- Java多线程——ThreadLocal类
一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名 ...
- 深入理解Java多线程——ThreadLocal
目录 定义 API 场景分析 场景实验,观察Spring框架在多线程场景的执行情况 10000此请求,单线程 10000次请求,线程数加到100 对c的访问加锁 把c设为ThreadLocal 收集多 ...
- Java 多线程--ThreadLocal Timer ExecutorService
ThreadLocal /** * ThreadLocal:每个线程自身的存储本地.局部区域 * @author xzlf * */ public class ThreadLocalTest01 { ...
- JAVA多线程---ThreadLocal<E>
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px ".SF NS Text" } tips: 1 当前ThreadLocal ...
- Java 多线程 - ThreadLocal
ref: https://www.cnblogs.com/chengxiao/p/6152824.html
- java多线程详解(5)-Threadlocal用法
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路. 使用这个工具类可以很简洁 ...
随机推荐
- Spring框架总结(六)
注解 注解方式可以简化spring的IOC容器的配置! 使用注解步骤: 1)先引入context名称空间 xmlns:context="http://www.springframework. ...
- ObjC正则表达式验证
试过ObjC的regkit这个框架. 也用过内置的正则表达式验证. 最后发现有个非常简单的方法就可以做到验证正则表达式.那就是NSPredicte这个类提供的方法. 这里有验证邮箱地址的正则为例: N ...
- WINAPI和APIENTRY是一样的
今天写线程函数时,发现msdn中对ThreadProc的定义有要求:DWORD WINAPI ThreadProc(LPVOID lpParameter); 不解为什么要用WINAPI宏定义,查了后发 ...
- Digester学习笔记(二)转载
为便于理解,将笔记的内容结构作了一些调整. 对象栈 对digester技术最普通的应用,是用来动态创建一个由Java对象构成的树结构,各对象的属性以及对象间的关系,基于XML文档的内容来设置(XML文 ...
- wc项目记录
1.Github项目地址:https://github.com/3116004700/ruanjiangongcheng 2.预估时间见PSP表格. 3.解题思路描述: 在看到这个项目的时候我就想到了 ...
- union 和 all union
sql union用法和sql union all用法,sql union效率 1.sql union用法 sql union在查询中可以将两个SQL 语句的结果合并起来.如果这样看的话, UNION ...
- js常用的校验代码 (整理)
/* 用途:检查输入手机号码是否正确 输入:str:字符串 返回:如果通过验证返回true,否则返回false */ function checkMobile(str){ var regu =/^[1 ...
- border使用小技巧
border-style 分类 dashed虚线类型 dotted 点线类型 double 双线类型 双线型量根实线的宽度和中间空白区域的间距有一定规律: 可以利用这个规律画出一些特殊的图案 代码如下 ...
- 高德地图之c#后台获取一个或多个起点到单个终点的直线距离
首先我们需要一个控制台添加一个新Key(可使用服务选择Web服务,测试的时候IP白名单先不填); 直线距离是通过后台get方式请求API服务地址http://restapi.amap.com/v3/d ...
- .net core 高性能对象映射
关于对象转换已经有不少轮子(AutoMapper,TinyMapper) .出于项目需要,手动造一个简单轮子.先贴代码 1.采用静态泛型类缓存,避免了拆箱装箱操作. 2.对于转换对象中有,字段名一样但 ...