Recent Posts
Archives

Posts Tagged ‘JavaParallelism’

PostHeaderIcon [DevoxxBE2025] Virtual Threads, Structured Concurrency, and Scoped Values: Putting It All Together

Lecturer

Balkrishna Rawool leads IT chapters at ING Bank, focusing on scalable software solutions and Java concurrency. He actively shares insights on Project Loom through conferences and writings, drawing from practical implementations in financial systems.

Abstract

This review dissects Project Loom’s enhancements to Java’s concurrency: virtual threads for efficient multitasking, structured concurrency for task orchestration, and scoped values for secure data sharing. Placed in web development contexts, it explains their interfaces and combined usage via a Spring Boot loan processing app. The evaluation covers integration techniques, traditional threading issues, and effects on legibility, expandability, and upkeep in parallel code.

Project Loom Foundations and Virtual Threads

Project Loom overhauls Java concurrency with lightweight alternatives to OS-bound threads, which limit scale due to overheads. Virtual threads, managed by the JVM, enable vast concurrency on few carriers, ideal for IO-heavy web services.

In the loan app—computing offers via credit, account, and loan calls—virtual threads parallelize without resource strain. Configuring Tomcat to use them boosts TPS from hundreds to thousands, as non-blocking calls unmount threads.

The interface mirrors traditional: Thread.ofVirtual().start(task). Internals use continuations for suspension, allowing carrier reuse. Consequences: lower memory, natural exception flow.

Care needed for pinning: synchronized blocks block carriers; ReentrantLocks avoid this, sustaining performance.

Structured Concurrency for Unified Task Control

Structured concurrency organizes subtasks as cohesive units, addressing executors’ scattering. StructuredTaskScope scopes forks, ensuring completion before progression.

In the app, scoping credit/account/loan forks with ShutdownOnFailure cancels on errors, avoiding leaks. Example:

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
    var credit = scope.fork(() -> getCredit(request));
    var account = scope.fork(() -> getAccount(request));
    var loan = scope.fork(() -> calculateLoan(request));
    scope.join();
    // Aggregate
} catch (Exception e) {
    // Manage
}

This ensures orderly shutdowns, contrasting unstructured daemons. Effects: simpler debugging, no dangling tasks.

Scoped Values for Immutable Inheritance

Scoped values supplant ThreadLocals for virtual threads, binding data immutably in scopes. ThreadLocals mutate, risking inconsistencies; scoped values inherit safely.

For request IDs in logs: ScopedValue.where(ID, uuid).run(() -> tasks); IDs propagate to forks via scopes.

Example:

ScopedValue.where(REQ_ID, UUID.randomUUID()).run(() -> {
    // Forks access ID
});

This solves ThreadLocal inefficiencies in Loom. Effects: secure sharing in hierarchies.

Combined Usage and Prospects

Synergies yield maintainable concurrency: virtual threads scale, scopes structure, values share. The app processes concurrently yet organized, IDs tracing.

Effects: higher IO throughput, easier upkeep. Prospects: framework integrations reshaping concurrency.

In overview, Loom’s features enable efficient, readable parallel systems.

Links:

  • Lecture video: https://www.youtube.com/watch?v=iO79VR0zAhQ
  • Balkrishna Rawool on LinkedIn: https://nl.linkedin.com/in/balkrishnarawool
  • Balkrishna Rawool on Twitter/X: https://twitter.com/BalaRawool
  • ING Bank website: https://www.ing.com/