Spring integration 执行器通道-InheritableThreadLocal问题

Spring integration 执行器通道-InheritableThreadLocal问题,spring-integration,Spring Integration,我正在使用executor通道进行并行调用 <task:executor id="taskExecutor" pool-size="5"/> <int:channel id="executorChannel"> <int:dispatcher task-executor="taskExecutor"/> </int:channel> 三,。测试激活器 @Component public class TestActivator {

我正在使用executor通道进行并行调用

<task:executor id="taskExecutor" pool-size="5"/>
<int:channel id="executorChannel">
    <int:dispatcher task-executor="taskExecutor"/>
</int:channel>
三,。测试激活器

@Component
public class TestActivator {

    public String testMethod(String name){
        System.out.println("GID from Inheritable thread local ->"+HeaderContext.getGID());
        return name;
    }
}
四,。测试班

@ContextConfiguration(locations = { "classpath:exec-channel-si.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class ThreadLocalGatewayTest {

    @Autowired
    TestGateway testGateway;

    @Test
    public void testBrokerageGateway() throws InterruptedException {

        for(int i=1;i<=5;i++){
            try {
                HeaderContext.setGID("gid"+i);
                System.out.println("done->" + testGateway.testMethod("name"+i));

            } finally {
                HeaderContext.clear(); 
            }
            Thread.sleep(2000);
        }
    }

}

好吧,我相信当您在服务中打印
ThreadId
时,您不会惊讶于为自己的目的重用线程:

name-> name1 in the inheritable thread local -> gid1 for thread: pool-1-thread-1
name-> name2 in the inheritable thread local -> gid2 for thread: pool-1-thread-2
name-> name3 in the inheritable thread local -> gid3 for thread: pool-1-thread-3
name-> name4 in the inheritable thread local -> gid4 for thread: pool-1-thread-4
name-> name5 in the inheritable thread local -> gid5 for thread: pool-1-thread-5
name-> name6 in the inheritable thread local -> gid4 for thread: pool-1-thread-4
name-> name10 in the inheritable thread local -> gid1 for thread: pool-1-thread-1
name-> name8 in the inheritable thread local -> gid2 for thread: pool-1-thread-2
name-> name9 in the inheritable thread local -> gid3 for thread: pool-1-thread-3
name-> name7 in the inheritable thread local -> gid5 for thread: pool-1-thread-5
这是简单测试的结果:

private static final ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();

@Test
public void testInheritableThreadLocal() throws InterruptedException {
    ExecutorService executorService = Executors.newCachedThreadPool();
    final CountDownLatch stopLatch = new CountDownLatch(10);
    for (int i = 1; i <= 10; i++) {
        final int j = i;
        try {
            threadLocal.set("gid" + i);
            executorService.execute(() -> {
                System.out.println("name-> " + "name " + j + " in the inheritable thread local -> "
                        + threadLocal.get() + " for thread: " + Thread.currentThread().getName());
                stopLatch.countDown();
            });
        }
        finally {
            threadLocal.remove();
        }
    }
    assertTrue(stopLatch.await(10, TimeUnit.SECONDS));
}
因此,每个线程都有自己的变量副本,在一个线程中对变量的更改不会影响另一个线程

主线程中的
InheritableThreadLocal
与普通
ThreadLocal
相同。只有获得该增益,新生成的子线程才会获得主线程的当前副本。这就是为什么我们看到每个新线程都有一个新的值,但是当重用该子线程时,就像在
ThreadPool
中一样,我们仍然看到它自己的旧值

请阅读更多关于此事的RTFM


希望clear

能与我们分享一些代码。我用简单的例子编辑了这篇文章。非常感谢你的帮助。
<task:executor id="taskExecutor" pool-size="2"/>
<context:component-scan base-package="sample.test"/>
<int:channel id="executorChannel">
    <int:dispatcher task-executor="taskExecutor"/>
</int:channel>

<int:gateway id="testGateway"
    service-interface="sample.test.TestGateway"
    default-request-channel="executorChannel">
</int:gateway>
<int:service-activator input-channel="executorChannel" ref="testActivator"/>
GID from Inheritable thread local ->gid1
output->name1
GID from Inheritable thread local ->gid2
output->name2
GID from Inheritable thread local ->gid1
output->name3
GID from Inheritable thread local ->gid2
output->name4
GID from Inheritable thread local ->gid1
output->name5
name-> name1 in the inheritable thread local -> gid1 for thread: pool-1-thread-1
name-> name2 in the inheritable thread local -> gid2 for thread: pool-1-thread-2
name-> name3 in the inheritable thread local -> gid3 for thread: pool-1-thread-3
name-> name4 in the inheritable thread local -> gid4 for thread: pool-1-thread-4
name-> name5 in the inheritable thread local -> gid5 for thread: pool-1-thread-5
name-> name6 in the inheritable thread local -> gid4 for thread: pool-1-thread-4
name-> name10 in the inheritable thread local -> gid1 for thread: pool-1-thread-1
name-> name8 in the inheritable thread local -> gid2 for thread: pool-1-thread-2
name-> name9 in the inheritable thread local -> gid3 for thread: pool-1-thread-3
name-> name7 in the inheritable thread local -> gid5 for thread: pool-1-thread-5
private static final ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();

@Test
public void testInheritableThreadLocal() throws InterruptedException {
    ExecutorService executorService = Executors.newCachedThreadPool();
    final CountDownLatch stopLatch = new CountDownLatch(10);
    for (int i = 1; i <= 10; i++) {
        final int j = i;
        try {
            threadLocal.set("gid" + i);
            executorService.execute(() -> {
                System.out.println("name-> " + "name " + j + " in the inheritable thread local -> "
                        + threadLocal.get() + " for thread: " + Thread.currentThread().getName());
                stopLatch.countDown();
            });
        }
        finally {
            threadLocal.remove();
        }
    }
    assertTrue(stopLatch.await(10, TimeUnit.SECONDS));
}
 * This class provides thread-local variables.  These variables differ from
 * their normal counterparts in that each thread that accesses one (via its
 * {@code get} or {@code set} method) has its own, independently initialized
 * copy of the variable.