Java 24 introduces Scoped Values, a powerful alternative to ThreadLocal that offers better performance and cleaner code for managing per-thread data. This is a preview language feature.
Here's an example of ScopedValue in action:
private static final ScopedValue<String> USER_ID = ScopedValue.newInstance();
public void handle(Request req, String userId) {
  ScopedValue.where(USER_ID, userId)
    .run(() -> handle(req));
}
private void handle(Request req) {
  String data = getData(req);
  // Do something else
}
private String getData(Request req) {
  return runQuery(req, USER_ID.get());
}
As shown above, ScopedValue provides a means to pass data (the userId) securely to a faraway method without using method parameters. The faraway method can access the data via the ScopedValue object. This eliminates the need to pass additional parameters explicitly through multiple method calls.
- Scoped Values are immutable once set inside 
ScopedValue.where(...). On the other hand,ThreadLocalallows values to be changed at any time, which can lead to inconsistent state across different parts of a request. - Scoped Values are automatically removed after the scope ends, whereas 
ThreadLocalrequires an explicit call toremove()to avoid memory leaks, especially in thread pools. - Scoped Values bind data to a specific execution scope, ensuring that when a new task starts on a thread, it doesn’t inherit values from a previous request. 
ThreadLocalstores data at the thread level, meaning values persist across multiple tasks when using a thread pool. - Scoped Values work well with virtual threads and structured concurrency APIs.
 
For comparison, here's the same example using ThreadLocal:
private static final ThreadLocal<String> USER_ID = new ThreadLocal<>();
public void handle(Request req, String userId) {
  try {
    USER_ID.set(userId);
    handle(req);
  } finally {
    USER_ID.remove(); // to prevent memory leaks
  }
}
private void handle(Request req) {
  String data = getData(req);
  // Do something else
}
private String getData(Request req) {
  return runQuery(req, USER_ID.get());
}
While ThreadLocal still has its uses, most new applications will benefit from Scoped Values’ immutability, automatic cleanup, and better thread management.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.