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为解决多线程程序的并发问题提供了一种新的思路. 使用这个工具类可以很简洁 ...
随机推荐
- 用Collections升降排序
//期末从业人员 总收入 资产总计等 升降 排序 if("qmcyry".equals(sss)){ if("desc".equals(orders)){ Co ...
- 在VS2010中使用Git【图文】(转)
出处:http://www.cnblogs.com/oec2003/archive/2012/11/13/2768860.html 在之前的一片博客<Windows 下使用Git管理Github ...
- UVALive 7752 Free Figurines (瞎搞)
题意:给定 n 个盒子,然后告诉你每个盒子在哪个盒子里,数值越大,盒子越大,给定你初态,和末态,问你最少要几步能完成,只有两种操作,一种是把一个盒子连同里面的小盒子放到一个空盒子里,另一种是把一个堆盒 ...
- perl读取excel
因为工作当中遇到要处理大数据的excel的玩意,最多的有几十万行.用perl的方式试试,看看效果如何. ppm install OLE::Storage_Lite #如果不安装这个,后面两个安装不了 ...
- java TimeZone类
TimeZone类主要是对时区的操作 下面是一个简单的例子 public static void main(String[] args) { // TODO Auto-generated method ...
- 编写高质量代码改善C#程序的157个建议——建议136:优先使用后缀表示已有类型的新版本
建议136:优先使用后缀表示已有类型的新版本 加后缀在某些情况下是很奇怪的形式,我们都不愿意看到OrderProcessor2这样的类型.但是,有的时候仍旧有必要这样做.最典型的是FCL中关于数字证书 ...
- ssh关于含有外键的传值中无法识别正确的action的原因和解决办法
在含有外键的表中,要保存一个值到这个外键时:逻辑思路:需要先将jsp页面的值传到相应的action中,在这个action中需要引入这个外键的实体层和DAO层(DAO层只需set方法),在执行函数中对于 ...
- redis整理の主从复制
redis 主从复制配置和使用都非常简单.通过主从复制可以允许多个 slave server 拥有和 master server 相同的数据库副本. 特点: (1).master 可以拥有多个 sla ...
- 记一次艰苦卓绝的Discuz x3 论坛升级过程
首先吐槽一下discuz 的官方论坛. 你要想下载到正确版本的discuz实在不容易找到. 有兴趣自己去看吧. 就是因为这个原因, 我本来想要安装x2.5版本(那时x3 还是Beta版本), 结果不小 ...
- Sublime Text 3 Settings
Preferences - Setting User - > : { "font_size": 14, "word_wrap": true, " ...