[ 
https://issues.apache.org/jira/browse/CAMEL-20199?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18100317#comment-18100317
 ] 

Guillaume Nodet commented on CAMEL-20199:
-----------------------------------------

_Claude Code on behalf of [~gnodet]_

h3. Status Analysis (as of July 2026)

After auditing the codebase, here is the current status of the four sub-tasks 
defined in this issue. The foundational infrastructure is fully in place — what 
remains is a tail of mechanical component-level conversions.

h4. Sub-task 1: Replace synchronized with ReentrantLock — Largely Complete

The massive alphabetical sweep across all components (PRs #14972 - #16848 by 
[~essobedo]) plus additional core work (PR #21703 by [~gnodet]) converted the 
vast majority of synchronized blocks.

*Remaining (~108 usages in ~48 files, production code only):*
||Category||Count||Convertible?||
|{{MllpSocketBuffer.java}} (single file)|29|Yes — prime candidate, 27% of all 
remaining|
|DOM/XML API safety ({{importNode}}, XPath)|~6|No — DOM spec requires it|
|CXF Continuation API|~4|No — third-party API contract|
|Dev/debug-only (DevSpanExporter, JFR console)|~10|Low priority — not on hot 
paths|
|Core engine (transacted exchanges, debugger)|~8|Mostly intentional|
|*Straightforward conversion candidates*|*~20-25*|Yes — {{GuardedTaskStore}}, 
{{A2AProgress}}, {{JwksCache}}, {{KeycloakPublicKeyResolver}}, 
{{MiloClientCachingConnectionManager}}, etc.|

Core is effectively clean. ~20-25 component-level usages could still be 
converted.

h4. Sub-task 2: Eliminate Problematic ThreadLocal Usage — Mostly Complete

The *ContextValue abstraction* is in place (PR #20702): JDK 17-24 uses 
ThreadLocal, JDK 25+ uses ScopedValue. 5 core usages already migrated.

*Remaining raw ThreadLocal (10 usages):*
||Risk||File||What it caches||
|HIGH|{{camel-reactive-executor-tomcat}} {{TomcatReactiveExecutor}}|Worker 
objects with ArrayDeque — on hot path, uses reflection on 
{{Thread.threadLocals}} (breaks with VTs). Core equivalent already migrated but 
this wasn't.|
|MODERATE|{{camel-snakeyaml}} {{SnakeYAMLDataFormat}}|Yaml parser instance — 
moderately heavy, created per VT and never reused. WeakReference partially 
mitigates.|
|LOW|{{AbstractCamelContext.componentsInCreation}}|HashSet — startup only|
|LOW|{{InternalRouteStartupManager.setupRoute}}|Route ref — startup only, 
cleared after|
|LOW|{{camel-xpath}}, {{camel-datasonnet}}, {{camel-jq}}, {{camel-as2}}, 
{{camel-univocity}}|Exchange refs or small arrays — lightweight, properly 
scoped|

h4. Sub-task 3: Use Semaphores for Concurrency Limiting — Complete

* {{BoundedExecutorService}} — semaphore-based ExecutorService wrapper, 
automatically applied by {{DefaultThreadPoolFactory}} when virtual threads + 
bounded queue
* SEDA {{virtualThreadPerTask}} — semaphore-gated concurrency with 
{{concurrentConsumers}} as cap
* Throttler EIP — already semaphore-based ({{ConcurrentRequestsThrottler}})
* Rejected execution policies (CallerRuns, Abort, Discard) all supported

h4. Sub-task 4: JMX Exposure of ThreadPerTaskExecutor — Complete

PR #21701 added {{ManagedVirtualThreadExecutorMBean}}, 
{{ManagedVirtualThreadExecutor}}, lifecycle hooks in {{LifecycleStrategy}} for 
non-{{ThreadPoolExecutor}} executors, full integration in 
{{JmxManagementLifecycleStrategy}}, and tests.

h4. Bonus: Configuration & Documentation — Complete

* {{camel.main.virtualThreadsEnabled=true}} property (PR #21743)
* Comprehensive {{virtual-threads.adoc}} (1185 lines) covering enablement, SEDA 
models, backpressure, ContextValue, best practices, examples

h3. Remaining Work (keeping open as umbrella)

||Priority||Item||Effort||
|High|Migrate {{TomcatReactiveExecutor}} to ContextValue (parity with 
{{DefaultReactiveExecutor}})|Small|
|Medium|Convert {{MllpSocketBuffer}} (29 synchronized methods) to 
ReentrantLock|Medium|
|Medium|Convert ~20-25 remaining component synchronized blocks|Medium|
|Medium|Migrate {{camel-snakeyaml}} Yaml caching away from ThreadLocal|Small|
|Low|Migrate context-passing ThreadLocals (xpath, datasonnet, jq, as2) to 
ContextValue|Small each|

Overall the issue is ~85-90% complete. Keeping open as an umbrella for the 
remaining component-level cleanup.


> Complete support of Virtual Threads
> -----------------------------------
>
>                 Key: CAMEL-20199
>                 URL: https://issues.apache.org/jira/browse/CAMEL-20199
>             Project: Camel
>          Issue Type: Improvement
>          Components: came-core
>            Reporter: Nicolas Filotto
>            Assignee: Guillaume Nodet
>            Priority: Major
>             Fix For: 4.x
>
>
> For full support of Virtual Threads, several sub-tasks need to be done:
>  * Avoid Lengthy and Frequent Pinning by replacing synchronized blocks with 
> ReentrantLocks (use the option {{-Djdk.tracePinnedThreads=full}} to print 
> stack traces when a thread blocks while pinned)
>  * Don't Cache Expensive Reusable Objects in Thread-Local Variables by 
> avoiding thread locals when possible since when using Virtual Threads, the 
> objects will never be reused so if the thread-local variables are never 
> reset, it will end up with an OOME.
>  * Use Semaphores to Limit Concurrency instead of relying on the size of the 
> thread pool when applicable
>  * Allow to expose {{ThreadPerTaskExecutor}} through JMX indeed so far it is 
> limited to {{ThreadPoolExecutor}}
> References 
> [https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html]



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to