java中ThreadLocal对象理解和使用

《Java源码分析》:ThreadLocal /ThreadLocalMap 《Java源码分析》:ThreadLocal /ThreadLocalMap首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set(Object obj) 到线程中的对象obj是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。 线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个 阅读详情

对ThreadLocal的理解

个人理解: 用一个ThreadLocal可以用来为每个线程独立存储一个对象,让每个线程都有唯一的副本。每一个线程读取的变量是对应的互相独立的。通过get和set方法就可以得到当前线程对应的值。

如果单单从使用的角度可以理解为(实际不是这样):
ThreadLocal相当于维护了一个map,key就是当前的线程,value就是需要存储的对象。

实际存储结构是:
线程Thread中维护了一个ThreadLocalMap对象,ThreadLocalMap对象是以ThreadLocal作为key,存储数据。一个Thread中可能会定义多个ThreadLocal对象。



使用ThreadLocal

代码如下:

package com.study.threadLocal使用;

import java.util.Random;

import org.apache.commons.lang3.StringUtils;

public class TestThreadLocal2 implements Runnable
{
	
    private static final ThreadLocal<TestObject> formatter = ThreadLocal.withInitial(() -> new TestObject());
    /*
     *                          ||
     */
    private static final ThreadLocal<TestObject> formatter2 = new ThreadLocal<TestObject>(){
        @Override
        protected TestObject initialValue()
        {
        	TestObject obj = new TestObject();
            return obj;
        }
    };
    
    public static void main(String[] args) throws InterruptedException {
        TestThreadLocal2 obj = new TestThreadLocal2();
        // 启动3个线程,线程名称分别为 0,1 ,2
        for(int i=0 ; i<3; i++){
            Thread t = new Thread(obj, ""+i);
            Thread.sleep(new Random().nextInt(1000));
            t.start();
        }
    }

    @Override
    public void run() {
    	String name = Thread.currentThread().getName();
    	// 给线程名称为0和1的线程的ThreadLocal中设置一个对象
    	if(StringUtils.equals(name, "0")){
    		TestObject obj = formatter.get();
    		obj.setName("小白");
            formatter.set(obj);
    	}
    	if(StringUtils.equals(name, "1")){
            TestObject obj = formatter.get();
    		obj.setName("小红");
            formatter.set(obj);
    	}
        System.out.println("ThreadLocal对象:"+formatter);
        System.out.println("Thread Name= "+name+" formatter = "+formatter.get());
        System.out.println();
    }
    
    
    static class TestObject {
    	private String name;

    	public String getName() {
    		return name;
    	}

    	public void setName(String name) {
    		this.name = name;
    	}
    }
}

运行结果如下:
在这里插入图片描述
同运行结果可以看出:ThreadLocal用的是static final 修饰,所以3个线程打印的ThreadLocal对象是同一个。而ThreadLocal中存储的的TestObject对象,每个线程都是不同的对象。


简单了解ThreadLocal源码

通过set方法简单看下源码:
先通过当前线程获取ThreadLocalMap对象。如果没有,则创建ThreadLocalMap,将value存入。
在这里插入图片描述
观察创建ThreadLocalMap对象,createMap方法会创建一个ThreadLocalMap对象,并把该对象赋值给当前线程的成员变量threadLocals。可以想得到,这个地方每个线程调用set时,t都是不同的。
在这里插入图片描述
ThreadLocalMap的构造方法:会将ThreadLocal经过hash得到一个下标作为key,将value存储到ThreadLocalMap中的table中。这个地方需要注意的是,ThreadLocal<?> firstKey针对于所有线程,都是同一个对象。但是看上一步赋值的时候,每个线程调用的t都是不同的。
在这里插入图片描述
每个线程持有一个ThreadLocalMap对象。每一个新的线程Thread都会实例化一个ThreadLocalMap并赋值给成员变量threadLocals,使用时若已经存在threadLocals则直接使用已经存在的对象。


借用ingxin大佬的总结:

1、对于某一ThreadLocal来讲,他的索引值i是确定的,在不同线程之间访问时访问的是不同的table数组的同一位置即都为table[i],只不过这个不同线程之间的table是独立的。
2、对于同一线程的不同ThreadLocal来讲,这些ThreadLocal实例共享一个table数组,然后每个ThreadLocal实例在table中的索引i是不同的。

java中的ThreadLocal详解及示例代码 ThreadLocal 根据名字我们可以知道这是一个线程本地变量,每一个线程都回copy一个副本,可以为创造对象减少不必要的开销(单例),但是不能保证线程安全(每个线程的结果可能是不一样的) ThreadLocal对比锁机制: 锁机制是以时间换空间,让多个线程依次访问一个资源 ThreadLocal是以空间换时间,每个线程拥有资源的一个副本,不会相互影响 ThreadLocal类常用方法: get:获得线程局部变量中的值 set:设置值 remove:删除值 initialValue:给值进行初始 阅读详情

相关推荐

群晖NAS安装HomeAssistant保姆级教程:从Docker部署到智能设备接入

本文提供了一份详尽的群晖NAS安装HomeAssistant保姆级教程,涵盖从Docker部署到智能设备接入的全过程。通过规划存储路径、配置容器环境变量和网络模式,确保系统稳定运行。教程还介绍了如何接入小米、苹果HomeKit等智能家居设备,并利用自动化与仪表盘打造本地化、高响应速度的智能中枢,实现数据隐私与远程控制的完美平衡。

play7的博客 694

ThreadLocal详解(应用及底层原理)

Java ThreadLocal 原理及应用详解

m0_50435987的博客 645

从牛顿冷却定律到热传导方程:一维热传导方程的物理直觉与数学推导

本文从牛顿冷却定律出发,结合傅里叶热传导定律和能量守恒原理,系统推导了一维热传导方程的数学形式。通过微元分析和物理直觉,揭示了温度随时间变化与空间二阶导数之间的关系,并阐释了热扩散率α的物理意义。文章还探讨了方程的边界条件、数值解法及其在材料科学和工程中的应用,为理解热量传递提供了清晰的物理图像和数学框架。

palm99的专栏 837

ThreadLocal 使用和原理

这篇文章会从三个方面来说说Threadlocal ThreadLocal用在什么地方? ThreadLocal的get/set源码分析! ThreadLocal的使用方法! 1、ThreadLocal用在什么地方? 1.1)保存线程上下文信息,在任意需要的地方可以获取。 例如Spring的事务管理,用ThreadLocal存储Connection,从而各个DAO可以获取同...

哲里哲里的博客 335

ENVI遥感数字图像处理方法(一)

文章目录1.查看图像的空间分布特征(一)生成灰度图像(二)生成假彩色图像(三)连接不同视图的影像2.查看图像的像元灰度值3.统计并查看图像直方图 1.查看图像的空间分布特征 在打开一幅遥感影像时,有两个文件,我们要选择数据文件来打开。 打开过后,点击Data Manager,查看该影像的波段 该影像共有6个波段 (一)生成灰度图像 步骤如下: (二)生成假彩色图像 先生成一个一般的假彩色图像: 再生成一个标准假彩色图像,将其存放在一个新的视图中: 标准假彩色图像波段构成为:近红外、红光波段、绿

江昊东的博客 5万+

告别理论!手把手教你用Patran/Nastran搞定机翼颤振分析(附完整模型文件)

本文提供了一份详细的机翼颤振分析实战指南,使用Patran/Nastran软件从零开始构建完整分析模型。涵盖几何建模、网格划分、模态分析到气动弹性耦合的全流程,特别适合航空航天领域工程师学习颤振分析技术。教程包含完整模型文件和实用脚本,帮助读者快速掌握这一关键飞行器设计技能。

weixin_30879169的博客 540

ThreadLocal理解及其内存泄露

ThreadLocal理解及其内存泄露

a974988176的博客 685

ET篇:Google.Protobuf的学习(理解基本的使用流程)

据我目前所知,ET使用的数据交换协议是Google.Protobuf,所以今天就来学习一下,但是网上许多人都是以高下立判的方式讲解的,对新手小白很不友好,所以我今天就以纯小白的视角和大家一起学习 学习环境: .NET Core2.2 .NET Framework 4.7.2 Rider protobuf-csharp-3.7.0-rc-2 Google.Protobuf简介 prot...

设计师养成记 3563

ThreadLocal

ThreadLocal可以保存一个共享变量,在多线程环境下,每个线程可以对自己所获取的变量副本进行操作,而不会影响其他线程的变量副本。 在ThreadLocal中主要有get()获取当前线程共享变量副本的值,set(T value)设置当前线程共享变量副本的值,intialValue()初始化当前线程共享变量副本的值。ThreadLocal初始化时可以重写intialValue进行初始化,否则默...

我的博客 460

postgresql 数据库 timescaledb 函数time_bucket_gapfill()报错解决及更换 license

最近在工作中使用postgresql 和 timescaledb 的time_bucket_gapfill()函数 报错,让更换license,在网上找了一大圈,没有找到,最后解决了这个问题,这篇文章记录我的解决办法查看timescaledb.license参数命令:show timescaledb.license;修改命令: 结果不行,报错如下:lter system set timescaledb.license=‘timescale’;那只能换包了如果出现上面那种情况,那我们只能先从官网上下载带 '

yang_z_1的博客 3249

Qcom camera hal简介

Qcom camera hal简介

weixin_42136255的博客 7764

详解ThreadLocal

Thread存储线程独有的变量(存储多个变量(值)时,可以创建多个ThreadLocal用来存储),以供在整个线程存活过程中取用。这种能力由ThreadLocal中的ThreadLocalMap实现。Thread在存储自己独有变量时,ThreadLocal实例在该Thread环境内使用set方法实现变量(值)存储。(继续探究原理)实际是静态内部类ThreadLocalMap将该变量(值)以key=ThreadLocal实例,value=变量(值)的键值对对象Entry形式存储到了ThreadLocalMap

文化园 4543

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

ThreadLocal 的使用

ThreadLocal 为每一个线程维护变量的副本,把共享数据的可见范围限制在同一个线程之内,因此 ThreadLocal 是线程安全的,每个线程都有属于自己的变量。 ThreadLocal<String> tl = new ThreadLocal<>(); tl.set("ping"); java.lang.ThreadLocal#set 源码 通过上面代码可知,每个 Thread 对象都维护了一个 threadLocals,它是 ThreadLocal 类中的静态..

m0_38077136的博客 171

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

java threadlocal 并发_java 并发,为线程创建本地变量 ThreadLocal的使用

packagetest;publicclassThreadLocalTest{publicstaticvoidmain(String[]args){ThreadLocaltl=newThreadLocal();Locall=newLocal();ThreadAta=newThreadA(tl);ThreadAtb=newThreadA(tl);ta...

weixin_39787089的博客 95

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ThreadLocal和引用关系

一、引用类型-强软弱虚 强引用:通常=表示的引用 软引用:SoftReference,在内存不足时,垃圾回收器才回收 弱引用:WeakReference,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。ThreadLocal中使用了弱引用 虚引用:最弱的一种引用,垃圾回收器直接回收,主要堆外内存管理场景。例如:通过虚引用关联一块堆外内存的对象,当虚引用对象被回收后,引用堆外内存还没有回收,因此需要通知(采用一个Queue方式)gc进行回收 二、ThreadLocal

程序员的世界 945

ThreadLocal内存泄漏问题

ThreadLocal很好地解决了线程之间需要数据隔离的问题,同时也引入了另一个问题,在应用程序中通常会使用线程池来管理线程,那么线程的生命周期与应用程序的生命周期基本保持一致,如果线程的数量很多,随着程序的运行,时间的推移,ThreadLocal类型的变量会越来越多,将会占用非常大的内存空间,从而产生内存泄漏,如果这些对象一直不被释放的话,可能会导致内存溢出。从图中可以看出,ThreadLocal对象存在于堆中,有栈中的强引用指向它,也有ThreadLocalMap中的entry的弱引用键指向他。

weixin_52394141的博客 1223

理解ThreadLocal

ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它

专注Android开发 659

ThreadLocal源码浅析

首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。 另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new 对象 的操作来创建的

泥土的博客 455

ThreadLocal详解

ThreadLocal

zhang_qing_yun的博客 360

深入浅出学java_深入浅出的学习Java ThreadLocal

前言ThreadLocal为变量在每个线程中都创建了一个副本,所以每个线程可以访问自己内部的副本变量,不同线程之间不会互相干扰。本文会基于实际场景介绍ThreadLocal如何使用以及内部实现机制。应用场景Parameter对象的数据需要在多个模块中使用,如果采用参数传递的方式,显然会增加模块之间的耦合性。先看看用ThreadLocal是如何实现模块间共享数据的。class Parameter {...

weixin_42310271的博客 213

【Java】浅谈ThreadLocal

ThreadLocal原理、ThreadLocal使用场景及ThreadLocal的内存泄露问题

weixin_53662229的博客 196

ThreadLocal源码解析

ThreadLocal ThreadLocal的作用: 1、是让每个线程都拥有自己的专属本地变量,即实现了线程隔离 2、可以通过ThreadLocal在同一线程的不同组件中传递公共变量 1、成员属性 * 用来寻址的hashcode * 使用 threadLocalHashCode & (table.length - 1) 计算结果得到的位置就是当前 entry 需要存放的位置。 */ private final int threadLocalHashCode = ne.

weixin_43478710的博客 613

java多线程之threadlocal的原理分析

jdk1.2版本就有解决多线程并发的工具类,threadlocal类本质上以空间换时间,让每一个线程拥有一份共享变量的副本,然后这样就没有多线程并发的问题,每一个线程都各自修改自己变量副本,互不影响, ThreadLocal的属性 ThreadLocal属性非常简单就是nextHashCode, 还有一个魔数HASH_INCREMENT变量,它是每次增加的这个固定的 数,就得到下一个Hash值,下面代码官方注释说明相比于连续的递增的hashcode,每次增加 固定魔数,对于2的n次方幂的数组效率更优,至

java111112313213的博客 159

ThreadLocal详解(转载)

ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量。 这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线程都在操作同一个变量,显然是不行的,并且我们也知道volatile这个关键字也是不能保证线程安全的。那么在有一种情况之下,我们需要满足这样一个条件:变量是同一个,但是每个线程都使用同一个初始值,也就是使用同一个变量的一个新的副本。这种情况之下ThreadLocal就非常使用,比如说DAO的数据库连接,我们知道D

u010797364的博客 349

ThreadLocal介绍-弱引用设计及验证

ThreadLocal的设计-重点弱引用

lswsmj的专栏 379
上一篇: 如何在项目中使用Active MQ
下一篇: Java关键字synchronized
村口老师傅
博客等级 码龄9年 67粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值