好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Netty分布式FastThreadLocal的set方法实现逻辑剖析

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

FastThreadLocal的set方法实现

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

线程set对象

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

new Thread( new Runnable() {

     @Override

     public void run() {

         Object obj  = fastThreadLocalDemo.fastThreadLocalTest.get();

         try {

             for ( int i= 0 ;i&lt; 10 ;i++){

                 fastThreadLocalDemo.fastThreadLocalTest.set( new Object());

                 Thread.sleep( 1000 );

             }

         } catch (Exception e){

             e.printStackTrace();

         }

     }

}).start();

我们跟到set方法中:

?

1

2

3

4

5

6

7

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方法中:

?

1

2

3

4

5

6

7

8

9

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中

?

1

2

3

4

5

6

7

8

9

10

11

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方法中:

?

1

2

3

4

5

6

7

public final void set(V value) {

     if (value != InternalThreadLocalMap.UNSET) {

         set(InternalThreadLocalMap.get(), value);

     } else {

         remove();

     }

}

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

跟进remove方法:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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方法

?

1

2

3

4

5

6

7

8

9

10

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方法:

?

1

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

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

以上就是FastThreadLocal的set方法的实现,更多关于Netty分布式FastThreadLocal的set方法的资料请关注其它相关文章!

原文链接:https://www.cnblogs.com/xiangnan6122/p/10208719.html

查看更多关于Netty分布式FastThreadLocal的set方法实现逻辑剖析的详细内容...

  阅读:15次