Interface ContextValue<T>
- Type Parameters:
T- the type of value stored in this context
This interface provides a unified API for sharing data within a thread context, with implementations that use either
ThreadLocal (for JDK 17+) or ScopedValue (for JDK 25+ with virtual threads).
The implementation is chosen automatically based on the JDK version and whether virtual threads are enabled via the
camel.threads.virtual.enabled system property.
Usage patterns:
- Read-only context passing: Use
where(ContextValue, Object, Runnable)to bind a value for the duration of a code block - Mutable state: Use
newThreadLocal(String)for state that needs to be modified after initialization
Important: When using newThreadLocal(String, Supplier), the values should be lightweight
objects. Heavy objects stored in ThreadLocal can lead to memory leaks (if threads are pooled) and increased
memory consumption (one instance per thread). Consider whether the object truly needs per-thread state, or if it can
be shared or passed as a parameter instead.
Example:
private static final ContextValue<String> ROUTE_ID = ContextValue.newInstance("routeId");
// Bind a value for a scope
ContextValue.where(ROUTE_ID, "myRoute", () -> {
// Code here can access ROUTE_ID.get()
processRoute();
});
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionget()Returns the value of this context variable for the current thread.booleanisBound()Returns whether a value is currently bound for this context variable.name()Returns the name of this context value (for debugging purposes).static <T> ContextValue<T> newInstance(String name) Creates a new context value with the given name.static <T> ContextValue<T> newThreadLocal(String name) Creates a new ThreadLocal-based context value with the given name.static <T> ContextValue<T> newThreadLocal(String name, Supplier<T> supplier) Creates a new ThreadLocal-based context value with the given name and initial value supplier.Returns the value of this context variable for the current thread, or the given default value if no value is bound.voidremove()Removes the value for this context variable (ThreadLocal-based implementations only).voidSets the value for this context variable (ThreadLocal-based implementations only).static <T> voidwhere(ContextValue<T> key, T value, Runnable operation) Executes the given operation with the context value bound to the specified value.static <T,R> R where(ContextValue<T> key, T value, Supplier<R> operation) Executes the given operation with the context value bound to the specified value.
-
Method Details
-
get
Returns the value of this context variable for the current thread.For ScopedValue-based implementations (JDK 21+), this will throw
NoSuchElementExceptionif called outside a binding scope. For ThreadLocal-based implementations, this returns the value set viaset(Object)ornullif not set.- Returns:
- the current value
- Throws:
NoSuchElementException- if no value is bound (ScopedValue implementation only)
-
orElse
-
isBound
boolean isBound()Returns whether a value is currently bound for this context variable.- Returns:
trueif a value is bound,falseotherwise
-
set
Sets the value for this context variable (ThreadLocal-based implementations only).This method is only supported by ThreadLocal-based implementations. For ScopedValue-based implementations, use
where(ContextValue, Object, Runnable)instead.- Parameters:
value- the value to set- Throws:
UnsupportedOperationException- if called on a ScopedValue-based implementation
-
remove
void remove()Removes the value for this context variable (ThreadLocal-based implementations only).This method is only supported by ThreadLocal-based implementations.
- Throws:
UnsupportedOperationException- if called on a ScopedValue-based implementation
-
name
-
newInstance
Creates a new context value with the given name.The implementation will use ScopedValue on JDK 21+ when virtual threads are enabled, otherwise it will use ThreadLocal.
- Type Parameters:
T- the type of value- Parameters:
name- the name for debugging purposes- Returns:
- a new context value
-
newThreadLocal
Creates a new ThreadLocal-based context value with the given name.This always uses ThreadLocal, regardless of JDK version or virtual thread settings. Use this when you need mutable state that can be modified after initialization.
- Type Parameters:
T- the type of value- Parameters:
name- the name for debugging purposes- Returns:
- a new ThreadLocal-based context value
-
newThreadLocal
Creates a new ThreadLocal-based context value with the given name and initial value supplier.This always uses ThreadLocal regardless of JDK version or virtual thread settings. The supplier is called to provide the initial value when
get()is called and no value has been set.- Type Parameters:
T- the type of value- Parameters:
name- the name for debugging purposessupplier- the supplier for the initial value- Returns:
- a new ThreadLocal-based context value with initial value support
-
where
Executes the given operation with the context value bound to the specified value.The binding is only visible to the current thread and threads created within the operation (for ScopedValue implementations).
- Type Parameters:
T- the type of valueR- the return type- Parameters:
key- the context value to bindvalue- the value to bindoperation- the operation to execute- Returns:
- the result of the operation
-
where
Executes the given operation with the context value bound to the specified value.- Type Parameters:
T- the type of value- Parameters:
key- the context value to bindvalue- the value to bindoperation- the operation to execute
-