Add virtual-threads-benchmark: re-run Spring Boot 4.1 / JDK 25 benchmarks, JEP 491 pinning fixed
Companion module for the rewritten post 'Virtual Threads on Spring Boot 4.1: The Benchmarks, Re-Run, and the Pinning Advice That Expired', retitled and re-benchmarked on Boot 4.1.1 / JDK 25.0.4.1 (the original post was written against Boot 3.4 / JDK 21). Covers: I/O-bound and CPU-bound throughput (platform vs virtual threads, including a JIT-warmup benchmarking bug this build caught and fixed), JEP 491 proof that synchronized no longer pins a virtual thread's carrier across a blocking call as of JDK 24 (obsoleting the old avoid-synchronized advice), proof that -Djdk.tracePinnedThreads=full is inert on JDK 25, and JEP 506's finalized ScopedValue API (JDK 25 GA, no --enable-preview, and a different shape than the old preview API). Kept as its own module rather than a new top-level repository, alongside the existing async/ module, which already has a stronger dual-JDK JEP 491 proof that this module's docs cross-link to instead of duplicating.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# 1. Enabling virtual threads on Spring Boot 4.1
|
||||
|
||||
[README](../README.md) | Next: [02-benchmark-methodology.md](02-benchmark-methodology.md)
|
||||
|
||||
Source: [`application.yml`](../src/main/resources/application.yml), [`DemoController.java`](../src/main/java/com/ankurm/vthreads/DemoController.java).
|
||||
Test: [`ThreadTypeTest.java`](../src/test/java/com/ankurm/vthreads/ThreadTypeTest.java).
|
||||
Transcript: [`docs/output/00-thread-type-confirmation.txt`](output/00-thread-type-confirmation.txt).
|
||||
|
||||
## Still one property
|
||||
|
||||
`spring.threads.virtual.enabled=true` is unchanged since Boot 3.2 and still the whole
|
||||
configuration surface for most apps on Boot 4.1. It requires JDK 21+; this repo runs it on
|
||||
JDK 25.
|
||||
|
||||
## What actually flips
|
||||
|
||||
Confirmed against a real running embedded server, not by reading the reference docs:
|
||||
|
||||
```
|
||||
enabled=false -> Thread: Thread[#9711,http-nio-auto-5-exec-1,5,main] | Virtual: false
|
||||
enabled=true -> Thread: VirtualThread[#9737,tomcat-handler-0]/runnable@ForkJoinPool-1-worker-2 | Virtual: true
|
||||
```
|
||||
|
||||
The platform-thread name prefix changed between the Boot 3 era and this repo's Boot 4.1 run
|
||||
(`http-nio-auto-5-exec-1` here vs. the `http-nio-8080-exec-3` shape in the older post) because
|
||||
this test binds to `server.port=0` (a random port) rather than a fixed 8080 -- Tomcat's
|
||||
connector-name-derived thread prefix reflects that. Cosmetic, but worth not being surprised by
|
||||
if your own logs look different from either example.
|
||||
|
||||
## Test infrastructure trap worth knowing about
|
||||
|
||||
Setting the property via `SpringApplicationBuilder.properties(...)` and expecting it to win
|
||||
over `application.yml` is a real bug this repo hit while building the benchmark below:
|
||||
`.properties(...)` binds to Spring's **`defaultProperties`** source, which has the *lowest*
|
||||
precedence of any property source Spring Boot recognizes -- lower than `application.yml`,
|
||||
which had `spring.threads.virtual.enabled: false` as its own explicit default. The fix was
|
||||
passing it as a command-line-style argument to `run(...)` instead
|
||||
(`"--spring.threads.virtual.enabled=" + value`), which binds at the highest precedence. See
|
||||
[`LoadBenchmarkTest.java`](../src/test/java/com/ankurm/vthreads/LoadBenchmarkTest.java) for
|
||||
where this was caught -- the first draft of the CPU-bound benchmark below silently ran both
|
||||
scenarios on platform threads and reported a difference that didn't exist.
|
||||
|
||||
Next: [02-benchmark-methodology.md](02-benchmark-methodology.md).
|
||||
Reference in New Issue
Block a user