Details
-
New Feature
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
None
-
None
Description
On Java 21, a virtual thread that blocks while holding a synchronized monitor pins its carrier thread (JEP 491 removes this in Java 24+, so this concerns Java 21 LTS users). Audit the remaining synchronized sites and replace those whose critical section can block on the socket, on an executor or on another lock; short in-memory sections (calendar formatting, lazy singletons, MBean registration) stay as they are.
Sites known to block under a monitor, all in the pool shutdown path:
- Pool.close(): awaits the appender executor and closes connections under synchronized(this).
- Pool.closeAll(): closes connections under synchronized(collection); the collection is a LinkedBlockingDeque whose iterator is weakly consistent, so the block is not needed at all.
- Pools.remove(), Pools.close(): await the shared idle-checker executor and close pools under synchronized(poolMap); keep the monitor for the map only and do the blocking work outside.
Also switch PrepareCache (eviction sends COM_STMT_CLOSE under the lock) and ConsoleLogger (console writes can block) to ClosableLock.
Verification
- Add an integration test, enabled on Java 21+, that runs the main driver paths on virtual threads (queries with calendar decoding, server prepared statements with a tiny cache, streaming, compression, pool churn and pool close) inside a JFR recording of jdk.VirtualThreadPinned, and fails if any event's stack reaches driver code. Ignore pins on JDK class-loader monitors (warm the workload up once before recording). This runs on the existing Java 21 and 25 CI jobs; no separate -Djdk.tracePinnedThreads job is needed.
- Confirm the test reports the pool-close pins against the driver before the change and none after.
- Tests must compile on the class path (surefire already runs them there) so that jdk.jfr is visible from test code.
Attachments
Issue Links
- is part of
-
CONJ-1361 require Java 17 (drop Java 8 and 11)
-
- Open
-