探究ThreadLocal的魔数0x61c88647和Entry数组

探究ThreadLocal

下面有一个很重要的HASH_INCREMENT,他的值是0x61c88647

public class ThreadLocal<T> {/***ThreadLocals依赖于附加到每个线程的每线程线性探针哈希映射 (thread.threadLocals和inheritableThreadLocals)。ThreadLocal对象充当键,通过threadLocalHashCode搜索。这是一个自定义哈希代码 (仅在ThreadLocalMaps中有用),它消除了在相同线程      *使用连续构造的ThreadLocals的常见情况下的冲突,同时在不太常见的情况下保持良好的行为。*/private final int threadLocalHashCode = nextHashCode();/*** 连续生成的哈希码之间的差异-将隐式顺序线程本地id转换为两次幂大小的表的近乎最佳扩展的乘法哈希值。*/private static AtomicInteger nextHashCode =new AtomicInteger();/*** 连续生成的哈希码之间的差异-将隐式顺序线程本地id转换为两次幂大小的表的近乎最佳扩展的乘法哈希值。*/private static final int HASH_INCREMENT = 0x61c88647;/*** 返回下一个哈希代码。*/private static int nextHashCode() {return nextHashCode.getAndAdd(HASH_INCREMENT);}//忽略}

0x61c88647:

0x是十六进制。

将61c88647放入进制转换器中:

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=D%3A%5C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%5CtyporaImags%5Cimage-20240331111553132.png&pos_id=img-HZxIlivU-1711857694460

二进制:1100001110010001000011001000111

十进制:1640531527

这个数字表示黄金比例乘以2的31次方 ((sqrt(5)-1) * (2^31))。结果是一个黄金数,即2654435769或-1640531527。

此外,在ThreadLocalMap的哈希处理方式中,我们可以看到HASH_INCREMENT与使用黄金比率的斐波那契哈希有关。标准的java.util.HashMap使用链表来解决哈希冲突。而ThreadLocalMap则只是寻找下一个可用的空间并将元素插入其中。它通过位掩码来找到第一个可用的空间,因此只有较低的几位是有效的。如果第一个空间已满,它会将元素放入下一个可用的空间。HASH_INCREMENT将键在稀疏的哈希表中分散排列,以减小找到相邻值的可能性。

因此,使用HASH_INCREMENT可以帮助减少ThreadLocalMap中哈希冲突的可能性,保证元素在哈希表中分布均匀。这样可以提高ThreadLocal的性能和效率。

其中使用了Entry[]

Entry对象是静态内部类

   static class Entry extends WeakReference<ThreadLocal<?>> {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}}

使用了WeakReference,这是弱引用。

Java中 4种引用的级别和强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用

当垃圾回收器回收时,某些对象会被回收,某些不会被回收。垃圾回收器会从根对象 Object来标记存活的对象,然后将某些不可达的对象和一些引用的对象进行回收。

表格说明如下:

引用类型被垃圾回收时间用途生存时间
强引用从来不会对象的一般状态JVM停止运行时终止
软引用当内存不足时对象缓存内存不足时终止
弱引用正常垃圾回收时对象缓存垃圾回收后终止
虚引用正常垃圾回收时跟踪对象的垃圾回收垃圾回收后终止

为什么使用Entry数组

是因为多线程的情况,要保证每个线程的副本值都有各自的值。

他用的是线性探测法。就是线程不多。不存在经常扩容的情况。

ThreadLocal 往往存放的数据量不会特别大(而且key 是弱引用又会被垃圾回收,及时让数据量更小),这个时候开放地址法简单的结构会显得更省空间,同时数组的查询效率也是非常高,加上第一点的保障,冲突概率也低

HashMap和ConcurrentHashMap1.8实现,不再展开。

开放地址法:容易产生堆积,不适合大规模的数据存储。删除其中一个冲突的元素时,需要移动元素。
链地址法:平均查找长度短,指针额外空间开销。适合大规模数据。

开放地址法
  即使key产生hash冲突,也不会形成链表,而是将所有元素都存入哈希表里。发生hash冲突时,就以当前地址为基准,进行再寻址的方法去寻址下一个地址,直到找到一个为空的地址为止。实现方式有:
1.线性探测法:发生hash冲突时,顺序查找下一个位置,直到找到一个空位置(固定步长1探测)
2.线性补偿探测法:在发生hash冲突时,在表的左右位置进行按一定步长跳跃式探测(固定步长n探测)
3.伪随机探测:在发生hash冲突时,根据公式生成一个随机数,作为此次探测空位置的步长(随机步长n探测),从而可以避免堆聚

缺点:容易产生堆积问题;不适于大规模的数据存储;散列函数的设计对冲突会有很大的影响;插入时可能会出现多次冲突的现象,删除的元素是多个冲突元素中的一个,需要对后面的元素作处理,实现较复杂;结点规模很大时会浪费很多空间

拉链法
  jdk1.8 中HashMap,ConcurrentHashMap都是采用这个方法,使用链表来保存发生hash冲突的key,即不同的key有一样的hash值,将这些发生冲突的 value 组成一个单向链表。
优点:
①拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短
②由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况
③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间
④在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可
缺点:
  指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度

再哈希法
  发生hash冲突时,使用第二个,第三个,第四个哈希函数来计算地址,直到无冲突时,比较耗时。

建立公共溢出区
  为所有发生hash冲突的关键字记录一个公共的溢出区来存放。在查找的时候,先与哈希表的相应位置比较,如果查找成功,则返回。否则去公共溢出区按顺序查找。在冲突数据少时性能好,冲突数据多的时候耗时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/783482.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Visual Studio 2022 中VLD库如何安装

GitHub链接 Release v2.5.1 KindDragon/vld 点击可执行程序进行下载 点击可执行程序进行安装 双击打开 一直点击next即可完成安装&#xff08;不用在意安装路径&#xff0c;总共不到2MB&#xff09; 如果GitHub无法打开&#xff0c;可以私信我发你安装包直接安装

MyBatis的高级特性探索

MyBatis 是一个流行的Java持久层框架&#xff0c;它提供了简单和直观的方法来处理数据库操作。相比于传统的JDBC操作&#xff0c;MyBatis通过XML或注解方式映射Java对象与数据库之间的关系&#xff0c;极大地简化了数据库编程工作。除了基本的数据映射和SQL语句执行功能&#x…

VBA批量读取txt文档目标数据并分组处理

VBA在批量处理txt等文本文件的数据是其数据处理的一大重要应用&#xff0c;实际在处理txt文档往往需要提取多个测试料的多个目标数值&#xff0c;而且还要将提取的数值进一步处理&#xff0c;如求取平均值&#xff0c;最小值等&#xff0c;能够直观地看到一组数据的规律&#x…

Java学习笔记NO.27

Java异常 异常处理在Java编程中是一项至关重要的技术&#xff0c;它有助于增强程序的稳定性和可靠性。 1.为什么需要处理异常&#xff1f; 在编写Java程序时&#xff0c;我们无法保证代码的100%正确性&#xff0c;因为各种意外情况可能会导致程序出现错误。这些意外情况包括但…

二维码门楼牌管理应用平台建设:实现民主参与的新途径

文章目录 前言一、二维码门楼牌管理应用平台的兴起二、投票表决功能的实现三、居民参与度的提升四、面临的挑战与前景展望 前言 在数字化时代&#xff0c;二维码技术的应用已经渗透到我们生活的方方面面。近期&#xff0c;二维码门楼牌管理应用平台的建设成为了社区治理的一大…

学习嵌入式系统开发学习课程有哪些

学习嵌入式系统开发需要掌握一些基础的编程知识和硬件知识&#xff0c;以下是一些常见的嵌入式系统开发学习课程和资源&#xff1a; 1. **C/C编程课程**&#xff1a;掌握好C/C编程语言是嵌入式系统开发的基础&#xff0c;可以通过在线教育平台如Coursera、Udemy、edX等搜索相关…

[flask]请求全局钩子

flask从入门到精通之钩子、异常、context、jinjia模板、过滤器 - 异步非阻塞 - 博客园 (cnblogs.com) 参考的这个博客&#xff0c;但有一个需要注意的是&#xff0c;最新版本的flask不知道是不是更新了还是怎么了&#xff0c;他的before_first_request不见了&#xff0c;如果继…

Vue2源码 —— 数据响应式实现

Vue2源码 —— 数据响应式实现 配置项 //package.json {"name": "vue","version": "1.0.0","main": "index.js","scripts": {"dev": "rollup -cw"},"author": "&…

Linux非root用户安装mysql5.7

1、下载安装包MySQL :: Download MySQL Community Server 点击Archives 我下载的是5.7.27版本&#xff0c;linux主机直接选择linux-Generic即可&#xff0c;选择第一个包下载即可 2、安装mysql 解压 shell> tar xzvf mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz shell&g…

VUE2实现元素抖动的指令

指令代码 要实现Vue2的指令&#xff0c;可以按照以下步骤进行&#xff1a; 创建一个指令对象。 export default {inserted: (el, binding) > {// 触发抖动效果if (!binding.value) return el.classList.remove(shake-animation)el.classList.add(shake-animation)const a…

抽象类和接口的简单认识

目录 一、抽象类 1.什么是抽象类 2.抽象类的注意事项 3.抽象类与普通类的对比 二、接口 1.接口的简单使用 2.接口的特性 3.接口的使用案例 4.接口和抽象类的异同 一、抽象类 所谓抽象类&#xff0c;就是更加抽象的类&#xff0c;也就是说&#xff0c;这个类不能具体描…

等级保护测评无补偿因素的高风险安全问题判例(共23项需整改)

层面 控制点 要求项 安全问题 适用范围 充分条件 整改建议简要 安全物理环境 基础设施位置 应保证云计算基础设施位于中国境内 1.云计算基础设施物理位置不当 二级及以上 相关基础设施不在中国境内 云平台相关基础设施在中国境内部署 安全通信网络 网络架构 应…

NFC RC522开发记录

文章目录 一、ID卡、IC卡(M1卡、CPU卡)的区别二、RC522读写操作1. 数据读写流程三、RC522驱动代码1. RC522 与 STM32 的接线图2. RC522.c3. RC522.h4. main.c一、ID卡、IC卡(M1卡、CPU卡)的区别 ID卡 :只存储了ID号,设备识别ID号,没有算法可言,容易复制,安全性低IC卡包含了…

ALPHA开发板上PHY网络芯片LAN8720:常用的几个寄存器功能

一. 简介 正点原子的开发板 ALPHA开发板&#xff0c;有线网络硬件方案所使用的也是最常用的一种方案&#xff0c;IMX6ULL芯片内部是自带 MAC网络芯片的&#xff0c;所以&#xff0c;也就是采用 "SOC内部集成网络MAC外设 PHY网络芯片方案"。 前面一篇文章简单了解了…

Asp.net Core 中一键注入接口

Asp.net Core 中一键注入接口 前言准备开始使用 前言 在之前开发Asp.Net Core程序时遇到接口需要一个一个的注入到Services中,当有非常多的接口需要注入时会显得代码成为了一座山,这里记录一下如何通过接口的命名一键自动注入. 准备 IDE: Visual studio 2022 .Net版本:.Net …

机器学习——最优化模型

最优化模型的概述&#xff1a; 从某种程度上说&#xff0c;我们的世界是由最优化问题组成的。每一天&#xff0c;我们的生活都面临无数的最优化问题&#xff1a;上班怎么选择乘车路线&#xff0c;才能舒服又快速地到达公司&#xff1b;旅游如何选择航班和宾馆&#xff0c;既省…

不可变集合及Stream流

若希望某个数据是不可修改的&#xff0c;就可以考虑使用不可变集合&#xff0c;以提高安全性&#xff1b;&#xff08;JKD9之后才有&#xff09; List不可变集合&#xff1a; public static void main(String[] args) {/*创建不可变的List集合"张三", "李四&q…

conda 创建 python3.10.12 环境

conda 创建 python3.10.12 环境 介绍使用前置条件&#xff1a;安装 conda配置环境变量验证 Conda 安装结果创建环境&#xff1a;python激活 Anaconda 环境 验证 Python 版本。 介绍 Conda是一个开源的包管理和环境管理系统&#xff0c;由Continuum Analytics公司开发。它可以安…

python之@overload

from typing import overloadoverload def repeat(s: str, count: int) -> str:...overload def repeat(s: bytes, count: int) -> bytes:...这段代码是在定义一个名为repeat的函数&#xff0c;其中使用了Python的类型注解和装饰器overload来进行重载&#xff08;Overloa…

批量爬取招聘网站【Boss直聘】上工作岗位的招聘信息

不管是学生还是工作的小伙伴&#xff0c;估计都对不同岗位工作几年的薪酬水平比较感兴趣。本文提供爬取招聘网站&#xff0c;获取某类工作招聘信息的实现逻辑和代码。具体的实施步骤是&#xff1a;明确爬取的招聘网站—确定爬取的工作城市—确定爬取的岗位—获取岗位的招聘子链…