• Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第2节: FastThreadLocal的set方法


     

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler

     

    第二节: FastThreadLocal的set方法

     

    上一小节我们学习了FastThreadLocal的创建和get方法的实现逻辑, 这一小节学习FastThreadLocal的set方法的实现逻辑

    set方法, 其实就是修改线程共享对象, 作用域只是当前线程, 我们回顾根据上一小节demo中, 其中一个线程set对象的过程:

    new Thread(new Runnable() {
        @Override
        public void run() {
            Object obj  = fastThreadLocalDemo.fastThreadLocalTest.get();
            try {
                for (int i=0;i<10;i++){
                    fastThreadLocalDemo.fastThreadLocalTest.set(new Object());
                    Thread.sleep(1000);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }).start();

    我们跟到set方法中:

    public final void set(V value) {
        if (value != InternalThreadLocalMap.UNSET) {
            set(InternalThreadLocalMap.get(), value);
        } else {
            remove();
        }
    }

    这里首先判断我们当前设置的对象是不是UNSET, 因为这里不是UNSET, 所以进到if块中

    if块调用了重载的set方法, 参数仍然为InternalThreadLocalMap, 有关InternalThreadLocalMap的get操作, 上一小节已经进行过分析, 这里不再赘述, 同时, 参数也传入了set的value值

    我们跟到重载的set方法中:

    public final void set(InternalThreadLocalMap threadLocalMap, V value) {
        if (value != InternalThreadLocalMap.UNSET) {
            if (threadLocalMap.setIndexedVariable(index, value)) {
                addToVariablesToRemove(threadLocalMap, this);
            }
        } else {
            remove(threadLocalMap);
        }
    }

    这里我们重点关注 if (threadLocalMap.setIndexedVariable(index, value)) 这部分, 这里通过threadLocalMap调用setIndexedVariable方法进行对象的设置, 传入了当前FastThreadLocal的下标和value

    我们跟到setIndexedVariable中:

    public boolean setIndexedVariable(int index, Object value) {
        Object[] lookup = indexedVariables;
        if (index < lookup.length) {
            Object oldValue = lookup[index];
            lookup[index] = value;
            return oldValue == UNSET;
        } else {
            expandIndexedVariableTableAndSet(index, value);
            return true;
        }
    }

    这里的逻辑其实和get非常类型, 都是直接通过索引操作的, 这里根据索引值, 直接通过数组下标的方式对元素进行设置, 熟悉上一小节内容的同学对此应该不会陌生

    回到FastThreadLocal的Set方法中:

    public final void set(V value) {
        if (value != InternalThreadLocalMap.UNSET) {
            set(InternalThreadLocalMap.get(), value);
        } else {
            remove();
        }
    }

    刚才我们分析了如果修改的对象不是UNSET对象的操作, 如果修改的对象是UNSET对象, 则会调用remove方法

    跟进remove方法:

    public final void remove(InternalThreadLocalMap threadLocalMap) {
        if (threadLocalMap == null) {
            return;
        }
        Object v = threadLocalMap.removeIndexedVariable(index);
        removeFromVariablesToRemove(threadLocalMap, this);
        if (v != InternalThreadLocalMap.UNSET) {
            try {
                onRemoval((V) v);
            } catch (Exception e) {
                PlatformDependent.throwException(e);
            }
        }
    }

     Object v = threadLocalMap.removeIndexedVariable(index) 这一步是根据索引index, 将值设置成UNSET

    我们跟进removeIndexedVariable方法:

    public Object removeIndexedVariable(int index) {
        Object[] lookup = indexedVariables;
        if (index < lookup.length) {
            Object v = lookup[index];
            lookup[index] = UNSET;
            return v;
        } else {
            return UNSET;
        }
    }

    这里的逻辑也比较简单, 根据index通过数组下标的方式将元素设置成UNSET对象

    回到remove方法中:

     if (v != InternalThreadLocalMap.UNSET) 这里判断如果我们设置的值不是UNSET对象, 则会调用onRemoval方法

    跟进onRemoval方法:

    protected void onRemoval(@SuppressWarnings("UnusedParameters") V value) throws Exception { }

    这里是个空实现, 用于交给子类去完成

    以上就是FastThreadLocal的set方法的实现

     

    上一节: FastThreadLocal的使用和创建

    下一节: recycler的使用和创建

  • 相关阅读:
    Oracle架构实现原理、含五大进程解析(图文详解)
    Oracle架构实现原理、含五大进程解析(图文详解)
    mysqldump --flush-logs
    mysql dump 参数
    Windows 8.1 PLSQL_32连接到RHEL6.1 Oracle10gr2_64
    Windows 8.1 PLSQL_32连接到RHEL6.1 Oracle10gr2_64
    echarts-单柱状图
    echarts-all.js:1 Dom’s width & height should be ready before init.
    如果是在有master上开启了该参数,记得在slave端也要开启这个参数(salve需要stop后再重新start),否则在master上创建函数会导致replaction中断。
    mysql 创建函数 error Code: 1227. Access denied;
  • 原文地址:https://www.cnblogs.com/xiangnan6122/p/10208719.html
Copyright © 2020-2023  润新知