Concurrency in real systems question 131 of 180 mid
How do you propagate request context (trace id, user) across threads?
- Static fields
- Correct: Copy it explicitly at the handoff: a
TaskDecorator, a wrapping executor, orScopedValuewith structured concurrency - It propagates automatically through executors
- Pass it in a database table
Context lives in ThreadLocals (MDC, SecurityContextHolder, tracing spans), and a ThreadLocal does
not follow work to another thread. Submitting to an executor loses all of it, which is why async logs
have no trace id.
The mechanisms, in increasing order of tidiness: capture the values before the handoff and restore them
inside the task, usually via a decorator that wraps every Runnable; use the framework's own bridge
(TaskDecorator, ContextSnapshot from Micrometer Context Propagation, Reactor's Context); or use
ScopedValue, final since Java 25 and a preview before that, which structured concurrency forks
inherit by design.
Whatever you use, the matching finally that clears the value belongs there too. Pooled threads keep
whatever you leave behind, and leaked context is worse than missing context: the next request logs
someone else's user id.
Quiz yourself on Concurrency in real systems Suggest a correction