You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WildFly 16频繁挂起:大量线程阻塞于Arjuna ThreadUtil.getThreadId求助

WildFly 16事务线程阻塞问题分析与解决方案

是否为已知问题?

这是Arjuna事务管理器在旧版本中的已知锁竞争问题。ThreadUtil.getThreadId是静态同步方法,会对ThreadUtil类对象加锁。当大量并发线程(如你的ScheduledThreadPoolExecutor定时任务线程)同时调用该方法时,会引发严重的锁阻塞,线程频繁等待锁导致CPU占用率飙升至100%,最终服务器无响应。

新版本是否已修复?

是的。后续版本的WildFly(如WildFly 20及以上)以及对应的Arjuna组件已重构ThreadUtil.getThreadId的实现,移除了静态同步锁,改用无锁的线程ID获取逻辑,彻底解决了该锁竞争问题。

除升级外的临时解决建议

除提高Arjuna日志级别用于问题排查外,可尝试以下方案缓解问题:

  • 调整ScheduledThreadPoolExecutor核心线程数,降低并发执行事务操作的线程数量,减少锁竞争压力。
  • 梳理定时任务逻辑,将不需要事务的代码移出事务边界,减少调用Arjuna事务API的频率。
  • 替换线程池实现:使用WildFly自带的JBoss线程池替代JDK原生的ScheduledThreadPoolExecutor,WildFly线程池与事务管理器兼容性更佳,能降低此类冲突概率。
  • 在Arjuna配置中添加参数com.arjuna.ats.arjuna.utils.ThreadUtil.disableThreadIdCache=true(注意:该配置可能影响事务性能,需测试验证后使用)。
  • 调整EJB严格最大池(StrictMaxPool)大小:线程栈显示问题发生在Stateless EJB实例销毁流程中,适当调小EJB池大小,减少并发销毁时的事务操作数量。

线程转储信息

java.lang.Thread.State: BLOCKED (on object monitor)
at com.arjuna.ats.arjuna.utils.ThreadUtil.getThreadId(ThreadUtil.java:71)
- waiting to lock <0x0000000542a53950> (a java.lang.Class for com.arjuna.ats.arjuna.utils.ThreadUtil)
at com.arjuna.ats.arjuna.coordinator.BasicAction.addChildThread(BasicAction.java:610)
- locked <0x000000071bc00b68> (a com.arjuna.ats.internal.jta.transaction.arjunacore.AtomicAction)
at com.arjuna.ats.internal.arjuna.thread.ThreadActionData.pushAction(ThreadActionData.java:93)
at com.arjuna.ats.internal.arjuna.thread.ThreadActionData.pushAction(ThreadActionData.java:69)
at com.arjuna.ats.arjuna.AtomicAction.begin(AtomicAction.java:124)
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.<init>(TransactionImple.java:104)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.begin(BaseTransaction.java:98)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.begin(BaseTransactionManagerDelegate.java:78)
at org.wildfly.transaction.client.provider.jboss.JBossLocalTransactionProvider.createNewTransaction(JBossLocalTransactionProvider.java:128)
at org.wildfly.transaction.client.LocalTransactionContext.beginTransaction(LocalTransactionContext.java:188)
at org.wildfly.transaction.client.ContextTransactionManager.begin(ContextTransactionManager.java:62)
at org.wildfly.transaction.client.ContextTransactionManager.begin(ContextTransactionManager.java:54)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:233)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.requiresNew(CMTTxInterceptor.java:388)
at org.jboss.as.ejb3.tx.LifecycleCMTTxInterceptor.processInvocation(LifecycleCMTTxInterceptor.java:68)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:60)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:53)
at org.jboss.as.ee.component.BasicComponentInstance.destroy(BasicComponentInstance.java:125)
at org.jboss.as.ejb3.component.stateless.StatelessSessionComponent$1.destroy(StatelessSessionComponent.java:69)
at org.jboss.as.ejb3.component.stateless.StatelessSessionComponent$1.destroy(StatelessSessionComponent.java:61)
at org.jboss.as.ejb3.pool.AbstractPool.doRemove(AbstractPool.java:80)
at org.jboss.as.ejb3.pool.AbstractPool.destroy(AbstractPool.java:69)
at org.jboss.as.ejb3.pool.strictmax.StrictMaxPool.stop(StrictMaxPool.java:171)
at org.jboss.as.ejb3.component.stateless.StatelessSessionComponent.done(StatelessSessionComponent.java:120)
at org.jboss.as.ejb3.component.EJBComponent.stop(EJBComponent.java:605)
at org.jboss.as.ee.component.ComponentStartService$2.run(ComponentStartService.java:78)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:485)

内容的提问来源于stack exchange,提问作者Carla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:12:07