Skip to content

Replace synchronized blocks with ReentrantLock; adopt virtual threads#718

Open
moqui-industrial wants to merge 1 commit into
moqui:masterfrom
moqui-industrial:feat/virtual-threads
Open

Replace synchronized blocks with ReentrantLock; adopt virtual threads#718
moqui-industrial wants to merge 1 commit into
moqui:masterfrom
moqui-industrial:feat/virtual-threads

Conversation

@moqui-industrial

Copy link
Copy Markdown

Summary

This PR makes the framework compatible with Java 21 virtual threads by eliminating carrier-thread pinning caused by synchronized blocks.

Changes

  • Replaces all synchronized methods and blocks with ReentrantLock throughout the framework (ExecutionContextFactoryImpl, EntityFacadeImpl, ServiceFacadeImpl, CacheFacadeImpl, and others)
  • Introduces VirtualThreadExecutorService — a thin wrapper over Executors.newVirtualThreadPerTaskExecutor() wired into the service facade
  • Adds VirtualThreadMoquiSuite and VirtualThreadStressTests to verify correctness and throughput under concurrent virtual-thread load

Why

Java 21 virtual threads are pinned to their carrier OS thread whenever they block inside a synchronized block or method. On a busy Moqui instance this causes carrier starvation, negating the benefits of virtual threads. Using ReentrantLock releases the carrier on block, allowing the JVM to schedule other virtual threads freely.

Test results

VirtualThreadStressTests (4 tests) all pass. Existing test suite unaffected.

…ual threads

All worker and job pools now use Thread.ofVirtual() via VirtualThreadExecutorService
(replaces WorkerThreadPoolExecutor / WorkerThreadFactory / JobThreadFactory).
allowCoreThreadTimeOut(true) prevents pooling so each task gets a fresh virtual thread.

synchronized methods across CacheFacadeImpl, ContextJavaUtil (EntityRecordLock,
ArtifactBinInfo), EntityDbMeta, EntityFacadeImpl, EntityFacadeImpl (statementExecutor),
ExecutionContextFactoryImpl (compileGroovy, webappInfo), GroovyScriptRunner, MCache,
MCacheManager, MEntry, MNode, ResourceFacadeImpl, ScheduledJobRunner, ScreenFacadeImpl,
ScreenTestImpl, TransactionFacadeImpl, and ElasticRequestLogFilter are replaced with
ReentrantLock to prevent carrier-thread pinning under virtual threads.

Thread.start(...) / new Thread(...).start() replaced with Thread.ofVirtual().name(...).start()
where applicable (XslFoTransform, RequireNewTx, EcfiReInit, ScreenTestRender).

Adds VirtualThreadMoquiSuite and VirtualThreadStressTests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant