Dubbo中InternalThreadLocal源码分析

在Java中,ThreadLocal是实现线程安全的一种手段,它的作用是对于同一个ThreadLocal变量,在每一个线程中都有一个副本,当修改任何一个线程的变量时,不会影响到其他线程。它通过在每一个Thread中存储一个类似于map的结构,以ThreadLocal变量为key,变量值为value。
Dubbo在RPC调用的上下文中,需要借助ThreadLocal保存上下文。它从Netty中借鉴了InternalThreadLocal的实现,与Java官方的ThreadLocal不同的是,它内部没有采用哈希表的结构,而是采用了数组作为内部实现。下面就来看一下具体是如何实现的。
InternalThreadLocal模块主要有以下几个类:
在这里插入图片描述

使用方式

参见RpcContext类中,定义了

	private static final InternalThreadLocal<RpcContext> LOCAL = new InternalThreadLocal<RpcContext>() {
   
        @Override
        protected RpcContext initialValue() {
   
            return new RpcContext();
        }
    };

获取线程本地变量,只需调用

	public static RpcContext getContext() {
   
        return LOCAL.get();
    }

重置

	public static void restoreContext(RpcContext oldContext) {
   
        LOCAL.set(oldContext);
    }

移除

	public static void removeContext() {
   
        LOCAL.remove();
    }

可以看出使用方式和官方的ThreadLocal是很类似的。

InternalThread

首先是InternalThread这个类,看它的类头和主要的field

/**
 * InternalThread
 */
public class InternalThread extends Thread {
   

    private InternalThreadLocalMap threadLocalMap;

以及获取和设置这个InternalThreadLocalMap变量的方法

	/**
     * Returns the internal data structure that keeps the threadLocal variables bound to this thread.
     * Note that this method is for internal use only, and thus is subject to change at any time.
     */
    public final InternalThreadLocalMap threadLocalMap() {
   
        return threadLocalMap;
    }

    /**
     * Sets the internal data structure that keeps the threadLocal variables bound to this thread.
     * Note that this method is for internal use only, and thus is subject to change at any time.
     */
    public final void setThreadLocalMap(InternalThreadLocalMap threadLocalMap) {
   
        this.threadLocalMap = threadLocalMap;
    }

从这个类可以看出,它跟官方的ThreaLocal的实现方式很像,也是通过一个内部的“map”来实现的。那么这个“InternalThreadLocalMap”真的是一个map吗?我们接着看。

remove

	public static void remove() {
   
	    // 获取当前线程
        Thread thread = Thread.currentThread();
        // 若是InternalThread则设置为null,否则调用ThreadLocal的remove方法
        if (thread instanceof InternalThread) {
   
            ((InternalThread) thread).setThreadLocalMap(null);
        } else {
   
            slowThreadLocalMap.remove();
        }
    }

destroy

	public static void destroy() {
   
        slowThreadLocalMap = null;
    }

nextVariableIndex

	public static int nextVariableIndex() {
   
		// 先返回值再加1,通过Atomic变量让该操作为原子操作
        int index = NEXT_INDEX.getAndIncrement();
        // 溢出处理
        if (index < 0) {
   
            NEXT_INDEX.decrementAndGet();
            throw new IllegalStateException("Too many thread-local indexed variables");
        }
        return index;
    }</
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值