Concurrency
virtual thread: 通常のThreadLocalは親から引き継がれない
親スレッドで設定した通常のThreadLocal値は、新しく開始したvirtual threadではnullになります。
SourceVirtualThreadLocals.java
Java 21
package examples.concurrency;
import java.util.concurrent.atomic.AtomicReference;
public final class VirtualThreadLocals {
private VirtualThreadLocals() {}
public static String valueSeenByVirtualThread(ThreadLocal<String> local)
throws InterruptedException {
AtomicReference<String> observed = new AtomicReference<>();
Thread worker = Thread.ofVirtual().start(() -> observed.set(local.get()));
worker.join();
return observed.get();
}
}TestVirtualThreadLocalsTest.java
Java 21
package examples.concurrency;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
class VirtualThreadLocalsTest {
@Test
void virtualThreadには親スレッドの通常のThreadLocal値が引き継がれない() throws InterruptedException {
ThreadLocal<String> requestId = new ThreadLocal<>();
requestId.set("req-42");
assertNull(VirtualThreadLocals.valueSeenByVirtualThread(requestId));
}
}01Assertion
このテストで確認できること
- 親スレッドのThreadLocalに値を設定する
- virtual threadから読むとnullになる
リクエスト文脈を非同期・並行処理へ渡す場合は、ThreadLocalへの暗黙依存を避け、明示的な値渡しを検討します。
OBSERVED RESULT
expected: virtual thread sees ThreadLocal → null
actual: null