Java跨线程传递数据

Java跨线程传递数据

  • 应用场景
  • 解决思路
  • 代码分析
    • JVM中工具
    • 阿里开源

应用场景

     对于单服务来说,比如一个普通的商城的服务,有一个接口返回商品的信息,针对不同的国家/地区可能有不同的搜索结果,需要根据入参识别所属国家,并将这个国家信息传递到下游接口使用,我们首先会想到用Java中提供的threadlocal类来存储线程私有的变量,在入口处识别国家信息放入threadlocal,在后续的使用中直接从threadlocal中获取即可。(本质上是通过线程持有的threadlocalMap来区分不同的线程);
      此外,对于公司级别的链路追踪系统一般通过提供jar包的方式,使用方可以通过jar包中的方法来向上下文中放置数据,在应用内部和应用中进行传递。

     上述两个场景都面临同一个问题:如果处理过程中,使用了线程池/或者新建了子线程,threadlocal就不好用了。因为新建的子线程的threadlocalMap中并没有存储对应的值,当我们把一些参数存储在threadlocal中时,应用内部使用线程池执行任务或者重新创建线程的时候,新的线程就无法访问到原有线程持有的threadlocal数据,threadlocal变量中存储的内容会丢失,(也就是上下文信息需要从创建任务的时刻传递到run这个线程的时刻)。

解决思路

     线程之间的通信方式主要有两大类,一种是通过消息的方式通信,另一种是共享数据来通信。

     上面两种方法,无非是在创建新的线程/线程池进行调度的时候,想办法把threadlocal变量传递过去,既然是在服务内部,共享数据的方式更为合理。

也就是说在创建新的线程/线程池进行调度这两个时候,需要调用者将threadlcoal变量存储一下,同时被调用者需要读一下。

代码分析

JVM中工具

首先,JVM中提供了InheritableThreadLocal来解决父线程和子线程之间共享threadlocal变量的问题。类的注释如下:

This class extends <tt>ThreadLocal</tt> to provide inheritance of values
* from parent thread to child thread: when a child thread is created, the
* child receives initial values for all inheritable thread-local variables
* for which the parent has values.  Normally the child's values will be
* identical to the parent's; however, the child's value can be made an
* arbitrary function of the parent's by overriding the <tt>childValue</tt>
* method in this class.

也就是说,如果变量声明为InheritableThreadLocal类型,保证在创建子线程的时候,就会将父线程的这些变量copy一下。
InheritableThreadLocal 继承自Threadlocal类,主要重写了三个方法,与threadlocal类中的createInheritedMap方法配合使用,在thread创建的时候判断父线程是不是有InheritableThreadLocal类型的变量,有的话则copy到子线程。
Java跨线程传递数据_第1张图片
Thread 类中的init方法部分节选:
Java跨线程传递数据_第2张图片
注意,InheritableThreadLocal 跨线程只适用于父线程/子线程之间的数据传递,对于线程池还是无能为力,还是需要封装出自己的runnable

阿里开源

阿里提供了一个开源的解决办法
https://github.com/alibaba/transmittable-thread-local
主要思想是:

Mythread thread = new Mythread(runs,CopyThreadLocalToContext);

## Run 的时候
Object  backup= setConextAndGetBackUp();
Run;
setBackup(backup);

除了这种对线程池进行显式包装的方式,还可以用java agent来对线程池进行增强,对代码没有入侵性

https://www.jianshu.com/p/a8f252d50d88

你可能感兴趣的:(java)