源码分析--ThreadLocal(一)

解决Java中的“找不到符号“错误 Java 开发中我们会遇到一种常见错误:找不到符号,这通常表示Java编译器不能识别我们在代码中使用的某个名字。这种错误通常是因为我们使用了未声明的变量、未导入的包、拼写错误的类名、方法名或变量名,或者我们在非类之外的地方调用了类中的非公共方法。这篇文章将详细阐述如何解决这类错误。 阅读详情

概述

以下内容来源于源码注释

ThreadLocal类提供了线程局部 (thread-local) 变量。这些变量与普通变量不同,每个线程都可以通过其 get 或 set方法来访问自己的独立初始化的变量副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

类图

在这里插入图片描述
内容提炼:

1、Thread 类有维护了一个属性变量 threadLocals (ThreadLocal.ThreadLocalMap threadLocals = null),也就是说每个线程有都一个自己的 ThreadLocalMap ,所以每个线程往这个 ThreadLocal 中读写隔离的,并且是互相不会影响的 。
2、ThreadLocalMap 类是 ThreadLocal 的静态内部类
3、ThreadLocalMap 维护了一个 Entry 数组,Entry 的 key 是 ThreadLocal 对象,value 是存入的对象,所以一个 ThreadLocal 只能存储一个Object对象,如果需要存储多个Object对象那么就需要多个 ThreadLocal
4、Entry 的 key 引用 ThreadLocal 是弱引用

源码分析

成员变量:

    /**
     * 初始容量 —— 必须是2的冥
     */
    private static final int INITIAL_CAPACITY = 16;

    /**
     * 存放数据的table,Entry类的定义在下面分析
     * 同样,数组长度必须是2的冥。
     */
    private Entry[] table;

    /**
     * 数组里面entrys的个数,可以用于判断table当前使用量是否超过负因子。
     */
    private int size = 0;

    /**
     * 进行扩容的阈值,表使用量大于它的时候进行扩容。
     */
    private int threshold; // Default to 0
    
    /**
     * 定义为长度的2/3
     */
    private void setThreshold(int len) {
        threshold = len * 2 / 3;
    }

内部类ThreadLocalMap :

public class ThreadLocal<T> {
  	// ThreadLocalMap 是 ThreadLocal 的静态内部类
	static class ThreadLocalMap {
        
		// Entry 是 ThreadLocalMap 的静态内部类
      	static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

          	// Entry 的 key 是 ThreadLocal 对象,value 是关联的数据对象
            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
      
        // ThreadLocalMap 维护了一个 Entry 数组,
      	private Entry[] table;
    }    
}

内部类:Entry

/**
 * Entry继承WeakReference,并且用ThreadLocal作为key.如果key为null
 * (entry.get() == null)表示key不再被引用,表示ThreadLocal对象被回收
 * 因此这时候entry也可以从table从清除。
 */
static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}

WeakReference是什么?

强引用(StrongReference):被强引用关联的对象不会被回收
软引用(SoftReference):被软引用关联的对象只有在内存不够的情况下才会被回收
弱引用(WeakReference):被弱引用关联的对象一定会被回收,也就是说它只能存活到下一次垃圾回收发生之前

WeakReference 是 Java 语言规范中为了区别直接的对象引用(程序中通过构造函数声明出来的对象引用)而定义的另外一种引用关系。WeakReference 标志性的特点是:reference 实例不会影响到被引用对象的 GC 回收行为(即只要对象被除 WeakReference 对象之外所有的对象解除引用后,该对象便可以被 GC 回收),只不过在被对象回收之后,reference 实例想获得被应用的对象时程序会返回 null。

其他常用方法后续学习补充~

Ubuntu 22.04 安装 IsaacLab 2.1.0 本文介绍了IsaacLab的完整安装流程:1)创建Python3.10虚拟环境;2)安装PyTorch2.5.1(CUDA11.8);3)升级pip并安装IsaacSim4.5.0;4)克隆IsaacLab仓库;5)运行安装脚本(需接受EULA)。若遇cmake缺失错误,需执行sudo apt安装。安装完成后可通过Ant-v0训练任务验证,成功运行后将显示IsaacSim窗口和训练完成提示。注意:IsaacSim不同版本可共存于不同环境。 阅读详情

相关推荐

Ubuntu22.04中通过conda快速部署PyTorch开发环境(CPU/GPU双版本实战)

本文详细介绍了在Ubuntu22.04系统中,如何利用Conda高效部署PyTorch开发环境。文章分别提供了CPU与GPU双版本的实战教程,涵盖环境创建、镜像加速、版本匹配及深度验证等关键步骤,旨在帮助开发者快速搭建稳定、兼容的深度学习环境,从而专注于模型开发。

rose2的博客 556

cmd运行java和javac命令报“找不到符号”或“找不到或无法加载主类”问题

今天运行两个java类,懒得打开eclipse跑,直接在命令行编译运行,结果竟然相继出现“找不到符号”和“找不到或无法加载主类”的错误。故贴此日志记录一下。 1、两个类如下: 1)Student.java: package com.liusw.test; public class Student { private Integer id; private String name;

nazhidao的专栏 1万+

Codesys 3.5报警功能配置保姆级教程:从变量定义到确认方式(含REF/ACK详解)

本文详细介绍了Codesys 3.5报警功能的配置流程,从变量定义到确认方式的选择,特别解析了REF和ACK两种确认方式的底层逻辑。通过实战案例和代码示例,帮助工程师快速掌握报警系统的搭建与调试技巧,提升工业自动化项目的可靠性。

weixin_29245767的博客 458

【Java错误录】

【编译错误和运行错误的区分】 一、基础知识 1.错误 错误(error)指程序运行时遇到的硬件错误,或者操作系统、虚拟机等系统软件错误或操作错误; 错误对于程序而言是致命的; 程序本身不能处理错误,只能依靠外界敢于,否则会一直处于非正常状态。如:没有找到.class文件 或者文件中没有main()方法等; java.lang.Error是错误类,产生错误时,java虚拟机生成并抛出Error类对象。如:没有main方法产生 NoClassDefFoundError,使用new分配内存时,没有可用内存产生

weixin_44135160的博客 649

ExcelVBA批量添加PDF文件

如图1所示,"BOM-01.xlsx"工作簿中的Sheet1工作表根据B列图号单元格中的内容,在图2所示的文件夹中找到对应的PDF文件,然后嵌入到相应的N列,双击N列中所示的图标,会打开PDF文件,是源文件的副本,即删除源文件,也可以打开N列的文件。 图1 根据B列的图号在N列嵌入对应的PDF文件 图2 PDF文件 图3 文件格式 Sub 导入文件() Ap...

qq389445046的博客 5574

uniapp [安卓苹果App端] - 在“安卓app/苹果app“平台端打包编译后,微信授权登录报错 login:fail [:-1]未能完成操作。(PGWXAPI错误-1。)错误码code:-10

uni-app,安卓Android,苹果ios,安卓app端,苹果App端,uniapp苹果安卓app,微信授权登录,uniAppAPP端微信登录报错,出现微信确认登录界面后点击登录报错,BundleID,应用ID,微信登录,app微信一键登录,微信登录绑定点确定就出错,AppSecrect,login:fail[:-1]未能完成操作。(PGWXAPI错误-1。),"errCode":-100,"code":-100,在uniappmanifest.json配置了AppSecrect还是报错无

🏆 前端领域优质创作者 3762

【已解决】java中错误:找不到符号

【已解决】java中找不到符号错误

蔓嘉的博客 2万+

如何设置Xilinx以太网IP核的Pause帧处理

这里要注意,为什么是或,第一个条件是该功能使能取反,也就是说,如果你设置使能不打开的话,这个条件是直接满足的;先来看图中第二句,判断该以太网数据包为Global Pause帧(gpp),首先要满足Step1,然后是由上图中第二句代码(assign global_pause_packet)后面的所有项“与”(&&)起来的,就是说要满足后面所有的项,分别是DA符合,SA符合,Etype符合,Opcode符合,并且使能了该功能(即设置ctl_rx_enable_gpp=1)。如果没通过,则进入Step3。

qq_43416206的博客 616

java:找不到符号

出现这种情况的原因之一:实体类的字段修改过。实体类中的变量名修改、然而其他地方调用的字段名还是修改之前的变量。

日常笔记 | 干货分享 | 毕设源码 | 毕设指导 | 答辩指导 1875

【AI智能体】全场景AI智能体工作台WorkBuddy实战操作详解

全场景AI智能体工作台WorkBuddy实战操作详解

congge 5487

RT-DETR模型应用过程中的报错处理及疑问解答,涉及环境搭建、模型训练、模块改进、论文写作

本文记录了RT-DETR模型的这一系列过程中可能发生的问题,以及大家非常关心的问题,这里统一做了一个记录和解答。

Limiiiing的博客 1764

【了不起的ThreadLocal】一、源码分析

文章目录一、前言二、ThreadLocal数据模型三、内存泄漏3.1 强引用存在内存泄漏?3.2 弱引用不存在内存泄漏?3.3 如何彻底避免内存泄漏?四、源码分析4.1 ThreadLocal源码4.2 ThreadLocalMap源码4.3 小结 一、前言 在JDK中,有些不起眼的类,往往蕴含着巨大的能量,ThreadLocal就是这样一个类,JDK1.2该类就诞生了,可算做JDK的一个元老了。...

温柔一cai刀 531

YOLOv8优化:独家创新(SC_C_Detect)检测头结构创新,实现涨点 | 检测头新颖创新系列

独家创新(SC_C_Detect)检测头结构创新,适合科研创新度十足,强烈推荐

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 4868

ThreadLocal源码分析 一

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。和HashMap不同的是当发生hash碰撞的时候它没有存成链表或红黑树,而是使用拉链法进行存储,就是同一个下标位置发生冲突时则+1向后寻址,知道找到空位置或垃圾回收位置进行存储。Java堆中每一个对象都有一个引用计数属性,引用每新增1次计数加1,引用每释放1次计数减1。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的。引:强引用、弱引用、软引用、虚引用。

qq_38254978的博客 991

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ThreadLocal源码分析一ThreadLocal类

ThreadLocal类提供线程局部变量。这些变量和其他普通的变量的区别在于,每个线程获取的线程局部变量都拥有自己相对独立的初始化过的副本。ThreadLocal的实例通常被声明为private static 来希望达到关联线程的状态的目的(例如:userId,transaction id)。 按我本人的理解有两点注意: 第一:ThreadLocal提供的线程局部变量通常都是新new的。这...

turbo_sky的博客 205

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

ThreadLocal和InheritableThreadLocal深入探究(一)源码分析

ThreadLocal和InheritableThreadLocal深入探究 ThreadLocal定义 此类提供线程局部变量。这些变量不同于正常的对应项, 因为每个线程访问一个有自己的、独立初始化的变量副本。实例通常是希望将状态与线程关联的类中的私有静态字段 (例如 用户id或事务id)。 官方示例 import java.util.concurrent.atomic.AtomicIntege...

java界的小学生 633

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

多线程的ThreadLocal类(一):ThreadLocal概览以及通过源码分析运行原理

ttt

蚩尤 249

ThreadLocal源码分析:(一)set(T value)方法

在ThreadLocal的get(),set()的时候都会清除线程ThreadLocalMap里所有key为null的value。 而ThreadLocal的remove()方法会先将Entry中对key的弱引用断开,设置为null,然后再清除对应的key为null的value。 本文分析set方法 ThreadLocal类的set方法 public void set(T value)...

noodleprince的博客 1450

并发编程(三)-ThreadLocal源码分析(一)

如果ThreadLocalMap对象不存在,说明当前线程还没有ThreadLocalMap对象,此时需要使用createMap方法为其创建一个ThreadLocalMap对象,并将ThreadLocal对象和初始值保存到其中。如果ThreadLocalMap对象不存在,说明当前线程还没有ThreadLocalMap对象,此时需要使用createMap方法为其创建一个ThreadLocalMap对象,并将ThreadLocal对象和值保存到其中。用于获取当前线程中ThreadLocal对象对应的值。

流星1688 281

大厂之路一由浅入深、并行基础、源码分析一 “J.U.C”之ThreadLocal深入分析

参考文献: 主要的参考文献:一文让你彻底明白ThreadLocal ThreadLocal使用与原理 拼多多面试官没想到ThreadLocal我用得这么溜,人直接傻掉 ThreadLocal相关介绍ThreadLocal的简单介绍ThreadLocal实现原理ThreadLocal实现原理之底层数据结构底层数据结构threadLocals之散列方式底层数据结构threadLocals之散列方式带来的哈希冲突底层数据结构threadLocals之初始容量及扩容可以被继承的ThreadLocal——Inh.

置身于量子事业的软件开发爱好者 543

ThreadLocal内存泄漏真因探究

ThreadLocal原理回顾 ThreadLocal的原理:每个Thread内部维护着一个ThreadLocalMap,它是一个Map。这个映射表的Key是一个弱引用,其实就是ThreadLocal本身,Value是真正存的线程变量Object。 也就是说ThreadLocal本身并不真正存储线程的变量值,它只是一个工具,用来维护Thread内部的Map,帮助存和取。注意上图的虚线,它代表一个弱引用类型,而弱引用的生命周期只能存活到下次GC前。 ThreadLocal为什么会内存泄漏 T.

进击30K的专栏 115

关于ThreadLocal深入分析

1.源码分析(下面是分析源码的一篇文章感觉很不错作者很用心,特转载) http://www.cnblogs.com/dolphin0520/p/3920407.html 2.ThreadLocal中remove ThreadLocal中利用了弱类型,可能会造成内存泄漏.为了避免此类事件发生要主动调用remove方法

dsq_csdn的博客 228

ThreadLocal详解

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

s_156的博客 243

TransmittableThreadLocal 原理分析

注:在看此篇文章前,你需要了解的原理。这里先总体的介绍(下文以ttl作为简称)的原理再去分析一些核心的源码,旨在先有个整体的认识,再去详细了解源码。由于是新建线程时复制父线程的本地变量到子线程,在线程池中由于线程只创建一次,因此无法复制新增的本地变量。ttl照着这个思路去找替代方案,在新建线程任务(Runnable)时将这些本地变量放到另一个类的属性字段中保存,这个类就是。下图的 holder 是一个,存的是当前线程的一个。

For-的博客 758

Handler源码解析(三)

Handler中ThreadLocal前言一、Handler中的ThreadLocal总结 前言 可能会有些乱套,我就是想搞点啥就搞点啥,来看看ThreadLocal。 一、Handler中的ThreadLocal 在之前呢可以通过 public static @Nullable Looper myLooper() { return sThreadLocal.get(); } 通过这个方法所得之,Loop的对象是保存在ThreadLocal中。接下来看看Thread

qq_42721092的博客 153
上一篇: 源码分析--ThreadPoolExecutor(二)
下一篇: 源码分析--ThreadLocal(二)
CodersCoder
博客等级 码龄10年 90粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值