Runnable is used
+ * to create a thread, starting the thread causes the object's
+ * run method to be called in that separately executing
+ * thread.
+ *
+ * The general contract of the method run is that it may
+ * take any action whatsoever.
+ *
+ * @see Thread#run()
+ */
+ @Override
+ public void run() {
+ log.info("ThreadLocal 的值为{}", ContextUtil.getThreadLocal());
+ log.info("TransmittableThreadLocal 的值为{}", ContextUtil.getTransmittableThreadLocal());
+ }
+}
+
diff --git a/concurrent/src/test/java/concurrent/ttl/TransmittableThreadLocalTest.java b/concurrent/src/test/java/concurrent/ttl/TransmittableThreadLocalTest.java
new file mode 100644
index 0000000..e6c297a
--- /dev/null
+++ b/concurrent/src/test/java/concurrent/ttl/TransmittableThreadLocalTest.java
@@ -0,0 +1,139 @@
+package concurrent.ttl;
+
+import cn.hutool.core.thread.ThreadUtil;
+import com.alibaba.ttl.TtlCallable;
+import com.alibaba.ttl.TtlRunnable;
+import concurrent.ttl.context.ContextUtil;
+import concurrent.ttl.task.CallableTask;
+import concurrent.ttl.task.RunnableTask;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+@Slf4j
+public class TransmittableThreadLocalTest {
+
+ static ExecutorService executorService;
+ static AtomicInteger atomicInteger;
+
+ @BeforeAll
+ public static void before() {
+ ContextUtil.setThreadLocal("wyl-01");
+ ContextUtil.setTransmittableThreadLocal("wyl-02");
+ executorService = ThreadUtil.newExecutor(3);
+ atomicInteger = new AtomicInteger(0);
+ }
+
+ /**
+ * 不修改值
+ *
+ * @param
+ * @return void
+ * @Date 2022/8/7
+ * @Author wangyl
+ */
+ @Test
+ public void runnableTest() throws InterruptedException {
+ for (int i = 0; i < 1000; i++) {
+ RunnableTask runnableTask = new RunnableTask();
+ executorService.execute(runnableTask);
+ }
+ Thread.sleep(10000L);
+ }
+
+ /**
+ * 修改值 线程池里值用的旧值
+ *
+ * @param
+ * @return void
+ * @Date 2022/8/7
+ * @Author wangyl
+ */
+ @Test
+ public void runnableChangeErrorTest() throws InterruptedException {
+ for (int i = 0; i < 1000; i++) {
+ RunnableTask runnableTask = new RunnableTask();
+ ContextUtil.setTransmittableThreadLocal("wyl-02-" + atomicInteger.incrementAndGet());
+ executorService.execute(runnableTask);
+ }
+ Thread.sleep(10000L);
+ }
+
+ /**
+ * 修改值线程池用的新值
+ *
+ * @param
+ * @return void
+ * @Date 2022/8/7
+ * @Author wangyl
+ */
+ @Test
+ public void runnableChangeRightTest() throws InterruptedException {
+ for (int i = 0; i < 1000; i++) {
+ RunnableTask runnableTask = new RunnableTask();
+ ContextUtil.setTransmittableThreadLocal("wyl-02-" + atomicInteger.incrementAndGet());
+ TtlRunnable ttlRunnable = TtlRunnable.get(runnableTask);
+ executorService.execute(ttlRunnable);
+ }
+ Thread.sleep(10000L);
+ }
+
+ /**
+ * 不修改值
+ *
+ * @param
+ * @return void
+ * @Date 2022/8/7
+ * @Author wangyl
+ */
+ @Test
+ public void callableTest() throws InterruptedException {
+ for (int i = 0; i < 1000; i++) {
+ CallableTask runnableTask = new CallableTask();
+ executorService.submit(runnableTask);
+ }
+ Thread.sleep(10000L);
+ }
+
+ /**
+ * 修改值线程池用的旧值
+ *
+ * @param
+ * @return void
+ * @Date 2022/8/7
+ * @Author wangyl
+ */
+ @Test
+ public void callableChangeErrorTest() throws InterruptedException {
+ for (int i = 0; i < 1000; i++) {
+ CallableTask runnableTask = new CallableTask();
+ ContextUtil.setTransmittableThreadLocal("wyl-02-" + atomicInteger.incrementAndGet());
+ executorService.submit(runnableTask);
+ }
+ Thread.sleep(10000L);
+ }
+
+ /**
+ * 修改值线程池里用的新值
+ *
+ * @param
+ * @return void
+ * @Date 2022/8/7
+ * @Author wangyl
+ */
+ @Test
+ public void callableChangeRightTest() throws InterruptedException {
+ for (int i = 0; i < 1000; i++) {
+ CallableTask runnableTask = new CallableTask();
+ ContextUtil.setTransmittableThreadLocal("wyl-02-" + atomicInteger.incrementAndGet());
+ TtlCallable