b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

三个例子说明了线程局部透明传输的问题

电脑杂谈  发布时间:2020-05-23 19:04:09  来源:网络整理

xpath实例使用详解_threadlocal使用实例_threadlocal 使用

Java中的

threadlocal绑定到一个线程. 您在一个线程中设置的值在另一个线程中不可用. 如果在threadlocal的并行线程中创建了新的子线程,则无法传递和共享其中的值(请考虑为什么先看不起). 这是透明传输的问题.

该值程之间透明地传输. 您可以将其视为错误. 这些问题通常更容易被掩盖,但是当问题暴露出来时,脾气就会越来越流行,使人们感到困惑和怀疑自己的生活.

作为代码的掌舵人,我们一定不能容忍这种问题. 本文适合于仔细研究. 我们以三个示例来说明通过编码方法解决此类错误的一般方法,以期实现的效果. 对于从事基础设施建设的学生来说,这是必不可少的知识点.

1,普通线程的ThreadLocal透明传输问题

2. sl4j MDC组件中的ThreadLocal透明传输问题

3. Hystrix组件的透明传输

因为涉及更多代码,所以xjjdog将这三个示例的代码放在github上. 如果您想深入研究,可以下载并调试它.

https://github.com/xjjdog/example-pass-through

为了更直观地理解,下面显示了一个异常代码.

threadlocal使用实例_threadlocal 使用_xpath实例使用详解

上面的代码在主线程中设置一个简单的threadlocal变量,然后想要在self线程中检索其值. 执行后,发现该程序的输出为: null.

该程序的输出与我们的预期有很大不同. 实际上,用InheritableThreadLocal替换ThreadLocal是可以的. 不要太早开心. 为了使用线程池,线程被缓存并重复使用,因为它们缓存线程. 此时,父子线程关系的上下文传递没有任何意义.

因此,线程池InheritableThreadLocal提交,并且获得的值可能在执行上一个任务后留下threadlocal使用实例,这是错误的. 使用仅是在执行任务时传输的常规功能.

上面的问题,transporttable-thread-local项目,已经得到很好的解决,并提供了Java代理支持.

让我们看一下最小集合的原始内容. 首先,让我们看一下ThreadLocal的结构.

ThreadLocal实际上作为键存在于Map中. 该映射是ThreadLocalMap,以私有变量的形式存在于Thread类中. 以上面的图片为例,如果我创建一个ThreadLocal,然后调用set方法,它将首先找到当前线程,然后找到threadLocals,最后将其存储为该映射中的键.

hread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
map.set(this, value);

为了能够完成多线程协调工作,必须提供全套的多线程工具. 包括但不限于:

1. 定义注释和由注释修改的ThreadLocal类

threadlocal 使用_xpath实例使用详解_threadlocal使用实例

定义一个新的ThreadLocal类,以便在分配值时,可以基于注释对其进行拦截和过滤. 这就要求在定义ThreadLocal时,我们使用提供的ThreadLocal类,而不是jdk提供的两个.

2. 在父线程和子线程之间复制数据

程池中提交任务之前,我们需要一个位置来临时存储父进程的ThreadLocal内容.

由于许多变量是私有的,因此您需要基于反射进行操作. 根据上面提供的ThreadLocal类的结构threadlocal使用实例,我们需要直接在其中操作变量表(这就是jdk不能随意更改变量名的原因).

在临时存储与父线程相关的变量之后,您可以使用活动设置和清理来完成变量的副本.

3. 提供专用的Callable或Runnable

那么这些数据如何组合?仍然依靠我们的任务载体类. 线程池通常通过Callable或Runnable提交线程. 以Runnable为例,让我们看一下这种调用关系.

以下类使用委托模型.

通过这种方式,只要我们在提交任务时使用自定义的Runnable即可;同时,使用自定义ThreadLocal,我们可以正常完成透明传输.

threadlocal使用实例_threadlocal 使用_xpath实例使用详解

sl4j MDC机制非常好,通常用于保存线程本地的“诊断数据”,然后打印日志组件,其内部实现是基于threadLocal的;但这有一些问题,主线程中的MDC数据集在子线程(多线程池)中不可用,下面将介绍如何解决此问题.

MDC(映射的诊断上下文),它是用于存储诊断日志的线程安全容器. 通常,在处理请求之前,将请求的唯一标识符放在MDC容器中,例如sessionId. 该唯一标签将与日志一起输出. 配置文件可以使用占位符进行变量替换.

类似于上述方法,我们需要提供专用的Callable和Runnable. 另外,为了能够同时支持MDC和普通线程,这两个类使用装饰器模式添加功能. 就单个类而言,外部表示仍然是委托模型.

相同的想法,相同的模式. 区别在于父线程的信息是临时存储的. 我们直接使用MDC的内部方法,并在执行任务之前和之后执行相应的操作.

相同的问题仍然存在于Netflix的保险丝组件Hystrix中. 在Hystrix线程池模式下,需要修改ThreadLocal的透明传输,并且它无法单独完成此功能.

但是,不能仅通过yml文件配置Hystrix策略. 我们指的是在Spring Cloud中扩展此策略,以开发我们自己的策略. 需要继承HystrixConcurrentStrategy.

构造代码仍然很长,您可以检查github项目. 但是有一个地方需要解释.

我们使用装饰器模式逐层嵌套代码,并添加了多线程透明传输功能和MDC传输功能. 这样,我们的类就可以同时在以上三个环境中具有透明的传输功能.

相同的想法可以用于其他组件. 例如,我们在多条调用链文章中提到了在多线程环境中跟踪信息的传输.

xpath实例使用详解_threadlocal使用实例_threadlocal 使用

通常将数据存储在当前线程中,然后在提交任务时将其包装. 值得注意的是,该方法相对侵入性强,适合于封装在通用的基本工具包中. 如果您在业务中使用此功能,您将被骂死.

那很好吗?

ThreadLocal将导致许多棘手的错误并导致代码污染. 在使用它之前,请确保您确实需要使用它. 例如,如果在SimpleDateFormat类上使用线程局部变量,则可以将其替换为DateTimeFormatter.

我们不擅长解决问题,我们只擅长解决容易出现问题的类.

作者简介: Smell(xjjdog),这是一个公共帐户,不允许程序员绕道而行. 专注于基础架构和Linux. 十年的体系结构和每天数百亿的流量将与您讨论高度并发的世界,并为您带来不同的口味. 我个人的微信xjjdog0,欢迎添加朋友以进行进一步的交流.

最近流行的文章

“必看!java后端,明亮的剑仙”“

相关和流行的后端技术指标

“分析Linux上最常用的命令(选择10年)” CSDN发布的第一天,得到1k的好评. 像是1/8.

“如果这次我不了解Spring Cloud的核心组件,那么我将徒劳地编写这个故事. ”用故事解释核心要素,您会感到满意

“ Linux生产环境中最常用的一套Sed”的“技巧”是Sed最常用的系列文章,通俗易懂. Vim的文章更容易理解.


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-219715-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...