大纲:

  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. Linux 配置nfs

    原文:http://www.cnblogs.com/mchina/archive/2013/01/03/2840040.html 一.NFS服务简介 NFS 是Network File System的 ...

  2. springboot+swagger集成

    一.swagger介绍 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.本文简单介绍了在项目中集成swagger的方法和一些常见问题.如果想深入分析项目源码,了解更多内容 ...

  3. Cannot change version of project facet Dynamic Web Module to 2.4.

    解决办法,找到项目目录,将.settings  target  .classpath  .project 删除 重新引入项目 原因是 web.xml 文件里<web-app 里的与.settin ...

  4. JavaScript执行顺序

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

  5. fwrite与fread

    函数原型 size_t fread(void *buffer, size_t size, size_t count, FILE *stream);   size_t fwrite(const void ...

  6. Reactor模式和NIO(转载二)

    本文可看成是对Doug Lea Scalable IO in Java一文的翻译. 当前分布式计算 Web Services盛行天下,这些网络服务的底层都离不开对socket的操作.他们都有一个共同的 ...

  7. Autoconf 中文手册

    Autoconf Autoconf Creating Automatic Configuration Scripts Edition 2.13, for Autoconf version 2.13 D ...

  8. 前端技术俗语js

    注:原文是英文,本文是我翻译的.有人把我翻译的内容原文照抄,放到他自己的专栏,搞得有人问我是不是我抄袭了……请支持我的劳动成果,花了两个小时翻译的,谢谢.转载请注明译者为方应杭. 嘿,我最近接到一个 ...

  9. opencv——播放视频

    #include "stdafx.h" #include <opencv2\opencv.hpp> #include <iostream> #include ...

  10. cesium编程入门(七)3D Tiles,模型旋转

    cesium编程入门(七)3D Tiles,模型旋转 上一节介绍了3D Tiles模型的位置移动,和贴地的操作,这一节来聊一聊模型的旋转, 参考<WebGl编程指南>的第四章 假设在X轴和 ...