大纲:

  1. 用法
  2. 源码

一、用法

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思想小结:

  1. 拿到当前线程对象。
  2. 拿到线程对象内部维护的ThreadLocalMap对象。
  3. 一个线程对象中只有一个ThreadLocalMap对象,所有ThreadLocal对象及这个ThreadLocal对象存储的值都以key-value的形式存在ThreadLocalMap中。(ThreadLocalMap的key是ThreadLocal对象,value是需要存储的变量。)

  

java多线程-ThreadLocal的更多相关文章

  1. Java多线程——ThreadLocal类的原理和使用

    Java多线程——ThreadLocal类的原理和使用 摘要:本文主要学习了ThreadLocal类的原理和使用. 概述 是什么 ThreadLocal可以用来维护一个变量,提供了一个ThreadLo ...

  2. [Java多线程]-ThreadLocal源码及原理的深入分析

    ThreadLocal<T>类:以空间换时间提供一种多线程更快捷访问变量的方式.这种方式不存在竞争,所以也不存在并发的安全性问题. //-------------------------- ...

  3. Java多线程ThreadLocal介绍

    在Java多线程环境下ThreadLocal就像一家银行,每个线程就是银行里面的一个客户,每个客户独有一个保险箱来存放金钱,客户之间的金钱不影响. private static ThreadLocal ...

  4. Java多线程——ThreadLocal类

    一.概述   ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名 ...

  5. 深入理解Java多线程——ThreadLocal

    目录 定义 API 场景分析 场景实验,观察Spring框架在多线程场景的执行情况 10000此请求,单线程 10000次请求,线程数加到100 对c的访问加锁 把c设为ThreadLocal 收集多 ...

  6. Java 多线程--ThreadLocal Timer ExecutorService

    ThreadLocal /** * ThreadLocal:每个线程自身的存储本地.局部区域 * @author xzlf * */ public class ThreadLocalTest01 { ...

  7. JAVA多线程---ThreadLocal<E>

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px ".SF NS Text" } tips: 1 当前ThreadLocal ...

  8. Java 多线程 - ThreadLocal

    ref: https://www.cnblogs.com/chengxiao/p/6152824.html

  9. java多线程详解(5)-Threadlocal用法

    ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路. 使用这个工具类可以很简洁 ...

随机推荐

  1. CodeForces 474B Worms (水题,二分)

    题意:给定 n 堆数,然后有 m 个话询问,问你在哪一堆里. 析:这个题是一个二分题,但是有一个函数,可以代替写二分,lower_bound. 代码如下: #include<bits/stdc+ ...

  2. Android 控件在布局中按比例放置[转]

    转自:http://netsky1990.blog.51cto.com/2220666/997452       在Android开发中常用到线性布局LinearLayout对界面进行具体的创建,其中 ...

  3. JavaScript执行顺序

    当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理.所以,就会出现当JavaScript解释器执行下面脚本时不会报错: alert(a);                ...

  4. Alpha冲刺(六)

    Information: 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Details: 组员1(组长)柯奇豪 - 过去两天完成了哪些任务 1. 基于ssm框架的前后端交互 ...

  5. SVN客户端--TortoiseSVN使用说明【转】

    TortoiseSVN是windows下其中一个非常优秀的SVN客户端工具.通过使用它,我们可以可视化的管理我们的版本库.不过由于它只是一个客户端,所以它不能对版本库进行权限管理. TortoiseS ...

  6. C/C++ Pthread线程

    线程按照其调度者可以分为用户级线程和核心级线程两种 用户级线程主要解决的是上下文切换的问题,它的调度算法和调度过程全部由用户自行选择决定,在运行时不需要特定的内核支持: 我们常用基本就是用户级线程,所 ...

  7. kafka安装配置及操作(官方文档)http://kafka.apache.org/documentation/(有单节点多代理配置)

    https://www.cnblogs.com/biehongli/p/7767710.html w3school https://www.w3cschool.cn/apache_kafka/apac ...

  8. 第一课 了解SQL

    1.1数据库基础 数据库:数据库是一个以某种有组织的方式存储的数据集合,可以想象是一个文件柜 数据库管理软件:DBMS用来操做创建数据库的软件 表:某种特定类型数据的结构化清单,数据库的下一层就是表 ...

  9. PyCharm创建普通项目配置支持jinja2语法

    打开项目的根目录的.idea文件夹中项目名.iml文件(隐藏文件) 打开这个iml文件,在component标签的同级,添加如下代码: <component name="Templat ...

  10. 减少C盘空间占用的技巧

    1.搜索C盘中大小大于某个值的文件:C:\Windows\SoftwareDistribution这个文件夹下很多大文件 2.搜索*.log文件 3.C:\Users\Guangshan\AppDat ...