Class TransmittableThreadLocal.Transmitter

java.lang.Object
com.alibaba.ttl.TransmittableThreadLocal.Transmitter
Enclosing class:
TransmittableThreadLocal<T>

public static class TransmittableThreadLocal.Transmitter extends Object
Transmitter transmit all TransmittableThreadLocal and registered ThreadLocal values of the current thread to other thread.

Transmittance is completed by static methods capture() => replay(Object) => restore(Object) (aka CRR operations); ThreadLocal instances are registered by method Transmitter#registerThreadLocal.

Transmitter is internal manipulation api for framework/middleware integration; In general, you will never use it in the biz/application codes!

Framework/Middleware integration to TTL transmittance

Below is the example code:

 ///////////////////////////////////////////////////////////////////////////
 // in thread A, capture all TransmittableThreadLocal values of thread A
 ///////////////////////////////////////////////////////////////////////////

 Object captured = Transmitter.capture(); // (1)

 ///////////////////////////////////////////////////////////////////////////
 // in thread B
 ///////////////////////////////////////////////////////////////////////////

 // replay all TransmittableThreadLocal values from thread A
 Object backup = Transmitter.replay(captured); // (2)
 try {
     // your biz logic, run with the TransmittableThreadLocal values of thread B
     System.out.println("Hello");
     // ...
     return "World";
 } finally {
     // restore the TransmittableThreadLocal of thread B when replay
     Transmitter.restore(backup); // (3)
 }

see the implementation code of TtlRunnable and TtlCallable for more actual code samples.

Of course, replay(Object) and restore(Object) operations can be simplified by util methods runCallableWithCaptured(Object, Callable) or runSupplierWithCaptured(Object, Supplier) and the adorable Java 8 lambda syntax.

Below is the example code:


 ///////////////////////////////////////////////////////////////////////////
 // in thread A, capture all TransmittableThreadLocal values of thread A
 ///////////////////////////////////////////////////////////////////////////

 Object captured = Transmitter.capture(); // (1)

 ///////////////////////////////////////////////////////////////////////////
 // in thread B
 ///////////////////////////////////////////////////////////////////////////

 String result = runSupplierWithCaptured(captured, () -> {
      // your biz logic, run with the TransmittableThreadLocal values of thread A
      System.out.println("Hello");
      ...
      return "World";
 }); // (2) + (3)

The reason of providing 2 util methods is the different throws Exception type to satisfy your biz logic(lambda):

  1. runCallableWithCaptured(Object, Callable): throws Exception
  2. runSupplierWithCaptured(Object, Supplier): No throws

If you need the different throws Exception type, you can define your own util method(function interface(lambda)) with your own throws Exception type.

ThreadLocal Integration

If you can not rewrite the existed code which use ThreadLocal to TransmittableThreadLocal, register the ThreadLocal instances via the methods registerThreadLocal(ThreadLocal, TtlCopier)/registerThreadLocalWithShadowCopier(ThreadLocal) to enhance the Transmittable ability for the existed ThreadLocal instances.

Below is the example code:


 // the value of this ThreadLocal instance will be transmitted after registered
 Transmitter.registerThreadLocal(aThreadLocal, copyLambda);

 // Then the value of this ThreadLocal instance will not be transmitted after unregistered
 Transmitter.unregisterThreadLocal(aThreadLocal);

The fields stored the ThreadLocal instances are generally private static, so the ThreadLocal instances need be got by reflection, for example:

 Field field = TheClassStoredThreadLocal.class.getDeclaredField(staticFieldName);
 field.setAccessible(true);
 @SuppressWarnings("unchecked")
 ThreadLocal<T> threadLocal = (ThreadLocal<T>) field.get(null);
Caution:
If the registered ThreadLocal instance is not InheritableThreadLocal, the instance can NOT inherit value from parent thread(aka. the inheritable ability)!
Since:
2.3.0
Author:
Yang Fang (snoop dot fy at gmail dot com), Jerry Lee (oldratlee at gmail dot com)
See Also: