当前位置: 首页 > 网络应用技术

ThreadLocal的未知细节

时间:2023-03-07 02:10:57 网络应用技术

  大家好,我是Axuan。

  让我们今天分析源代码。

  说到线路局部,我们仍然在日常开发中使用了很多。

  例如,当用户登录时,我们可以通过ThreadLocal保存用户的信息,而不是每次使用时再次检查它。

  弹簧中的语句也可以通过ThreadLocal保留,因此多个SQL语句使用相同的数据库链接来确保交易。

  好的,没什么可说的,我们开始了。

  首先查看整体结构

  变量保存在线程类中

  是的,内部类,基础数据结构是

  元素是类,此类是内部类,继承了类

  可以看出,钟K是,即我们通常所说的在这个地方,然后再谈论它。

  好吧,螺纹锁定的整体结构已经完成。让我们开始观看他的核心方法。

  第一个是方法。当我们使用它时,我们必须先存储它,然后拿走它,所以让我们看看他如何首先存储它。

  首先调用该方法以获取当前线程保留

  刚才说,线程类中的变量

  如果首先执行空气

  调用ThreadLocalMap

  在这里,我们可以看到基础数据结构是。

  首先构造默认长度,然后计算。

  螺纹局部的值称为变量。该方法调用该方法。此方法是调用静态实例方法。

  请注意,此变量是,每个新变量都是基于上一个变量构建的。

  让我们看一下这个变量。该值是转换为10个防护措施的。

  看到这一点,一定有一个非常自然的人。为什么每次都会添加另一个价值?

  让我们先看看一个

  该程序是为了模拟行中的threadlocal实例的创建。他的分布,让我们看看结果如何

  没有人出价,长度就是看到长度

  同样,没有竞标,不是很棒吗?

  这实际上包含一些。让我们看看这个数字是如何来自这个数字的

  改变上述公式;

  这个价值是什么?

  数字更好的朋友可能会立即想到,这不是我们在初中学习的!

  因此,每当主题码增加时,合理的分布都会均匀分布,原因在这里。有兴趣的朋友可以学习。

  我们继续看不见,方法设置将在初始化完成后调用

  这里的阈值不一样。哈希图更设置。他在这里。

  第一个初始化后,在调用第二个呼叫时呼叫的方法

  一样,通过数组的周期(找到合格的键)是下一个获得数组的键

  因为数组是,当数组数在范围内穿越时,它将返回到较低的出价。

  在周期中,第一个判断,如果直接值相等。

  第二个判断是当前数组的值,如果它为空。

  请注意,当前索引位置为null,但不是零。这是前面提到的问题。

  在Java中,它分为4种类型。这四个DAFA国王是我们日常工作中使用的参考文献。例如,用户a = new user(),A是强有力的参考,包装,包装和包装。

  虚拟吸引的使用通常用于链接,并通过虚拟吸引使用实现。每次发生,它只有在其进入时才会回收。

  条目的关键是修改的,因此每次发生时,它都会变得无效,但不会被回收。然而,结果,记忆的这一部分不能正常使用并引起。

  好吧,我们继续看不起。

  实际上,从这里可以看出,使用该处理,也就是说,如果计算出的索引位置被他人占据,那么看看下一个索引位置是否已被占用,总是找到或找到。

  看他的替代方法

  此方法有点长,让我们仔细看一下。

  首先,我们现在知道当前阵列的当前标签是为null的,稍后将被缝。然后,我将查看钥匙在null之前的钥匙。如果不是更好。元素,它将跳到遍历。

  这里可能有一些朋友。如果我从未遇到过空,我会回过头来吗?

  很明显不是。

  您是否忘记,当数组的元素数量达到一定值时,它将是,因此数组中会有一些较低的出价。

  再次查看,这一次,如果找到符合条件的键

  由于索引位置为无效,因此将在以后清理,因此请替换他和价值的位置。如果您没有找到它,则将其设置为I,否则您将开始从以前发现的索引位清理。

  有两种清理方法,首先查看其中一种方法,该方法

  因为清理是从开始的,所以位置的元素是空的。

  然后,将其直接从Null的钥匙下丢弃。

  如果您不是零,则可以计算出价。如果您发现计算出的招标位置不是您自己的位置,则意味着在最初设置的集合集合并被迫向后穿越时,正在计算计算出的索引位置。

  然后,将当前位设置为

  为什么设置为空?

  因为目前,一些钥匙的元素已经清理了,并且目前占据他的位置的元素很有可能,因此他想重新夺回属于自己的东西并笑。

  此后,他立即开始从计算的位置找到它,直到找到它。

  最后,我回到了我。请注意,我的位元素是为了。

  返回外层,再次清理,调用该方法

  在这里请注意,由于当前的I位元素是为了,因此从遍历的开头开始遍历。如果找到键,请再次致电以前的方法开始清洁。

  如果找不到钥匙,则将再次循环,发现和循环。

  再次返回外部方法,如果判断为空之前是否有任何条目,并设置了开始清洁而无需找到它的位置。

  它一直都进入该元素,如果找到了合格的。添加了新插入到该位置。因为在上一个周期中找到了合格的钥匙,并且没有进行清理,则可以在此工作。时间。之前的骑自行车电话的方法。

  返回开始方法,如果在周期中找不到合格的键,也找不到键,则它将构造一个要分配给该位置的元素。

  通常,在添加新元素后,它将被判断是否需要,因此目前还将判断它可以扩展,但是在扩展之前将执行一次。如果键的元素被清洁,则由于减少数组的数量而减少数组的数量,因此它将相同。无需再判断扩展。如果未清理,此时的判决超过了扩展。

  在实际扩展之前,将清理阵列以清洁钥匙的元素。这个方法

  可以看出,该数组再次在这里旅行,并打电话给呼叫进行清理。

  清洁后,确定是否超过阈值,并将阈值降低为原始。

  作者可以考虑,在清洁后,如果要素的数量超过阈值,那么它肯定会超过它的时间,而不是在当时扩大容量。

  要求扩展

  该方法相对简单,即阵列容量加倍,然后旧数组的元素到新数组,

  让我们在这里进行分析,让我们看看

  该方法相对简单。首先,获取当前线程的变量。如果为null,请调用初始化

  该方法返回方法,然后调用前面提到的方法。

  如果变量不是null,请调用输入元素。

  在这里,如果满足计算的I索引位置,则返回,否则调用方法

  如果e为空,则意味着它已被回收并返回。

  最后,我返回方法以确定是否找到条件,然后返回以找到它。我没有找到持续的呼叫方法。当前实例用作键,作为一个值,并且构造一个被插入数组中。

  终于看方法

  呼叫方法

  计算当前实例所在的索引位置,确定该位置是否是您自己,是的,然后调用方法以查看是否可以清理某些元素然后返回。

  在我们的日常工作中,如果在线工作存在问题,则需要调查,现在微型服务占上风。许多项目分为传统单体拆除的微服务。通常,客户的一个请求将通过多个系统。这次,为了跟踪整个链接的呼叫,我们通常会创建一个以渗透整个呼叫链接。这样,我们可以在检查日志时通过此连接整个呼叫过程。

  但是,为了提高系统的快速响应能力,我们经常为异步执行创建。目前,我们将打破。如果线程池的实现存在错误,则无法跟踪它。

  目前,我派上用场。

  日志框架中有一个呼叫的类,可以通过他实现我们需要的功能。

  让我们看一下在正常情况下打电话的过程。

  首先要进入过滤器的请求,我们将在这里为他设置一个

  然后要求请求

  服务课

  线程池配置类

  它主要用于示范,并保存了一些异常捕获。

  YAML配置

  运行程序,打印结果

  可以看出,获得螺纹池中的线程,无法获得。

  我们稍微改变下线池的配置类

  我们打包需要执行的任务

  再次执行打印结果

  可以看出,目前已获得线程池中的线程,从而完成了链接跟踪的功能。

  让我们简单地看看如何实现此功能。

  让我们看看刚刚使用的方法

  可以看出,MDC只是一个外墙,真正有效的是这件事。

  实际上,这是一个接口,该功能由他的子类实现

  现在我们的日志框架通常使用。

  可以看出,核心是地图变量。从名称可以看出

  没错,他是一个,一切都被它包围了。

  本文将本文的源代码分析为他在实际工作中的使用。实际上,朋友可以发现许多技术的底部是我们所熟悉的,但是在包装层之后,我们穿上了各种各样的华丽背心,我们不再认识他,但是当您迈出一步步骤,当您像一层一样剥落他时,最后,您忍不住了,哦---,所以,Sogaessence

  原始:https://juejin.cn/post/709895167121658917