RUNNABLE Thread.State but in Object.wait()

2022-09-03 00:32:16

我已经提取了我的容器进程的JStack,并让线程在那里运行,以下分布分组为:Thread.state

count    thread state
   67    RUNNABLE
    1    TIMED_WAITING (on object monitor)
    8    TIMED_WAITING (parking)
    4    TIMED_WAITING (sleeping)
    3    WAITING (on object monitor)
   17    WAITING (parking)

对于可运行的线程,我有以下描述:

"http-bio-8080-exec-55" daemon prio=10 tid=0x000000002cbab300 nid=0x642b in Object.wait() [0x00002ab37ad11000]
   java.lang.Thread.State: RUNNABLE
    at com.mysema.query.jpa.impl.JPAQuery.<init>(JPAQuery.java:44)
    at net.mbppcb.cube.repository.TransactionDaoImpl.findByBusinessId(TransactionDaoImpl.java:73)
    at sun.reflect.GeneratedMethodAccessor76.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    ...

如上所示,处于 RUNNABLE 状态的线程数随时间增加,并且似乎挂起。如果它们假设被阻止,它们不应该处于“已阻止”状态吗?或者它们应该处于等待状态?有RUNNABLE线程很奇怪,但在Object.wait()中不是吗?

更新 1

我可以在文档中看到:

处于可运行状态的线程正在 Java 虚拟机中执行,但它可能正在等待来自操作系统的其他资源,如处理器。

如何确定线程在等待什么?


答案 1

这似乎是类初始化死锁

JPAQuery构造函数正在等待依赖类的初始化,可能是:JPAProvider

    public JPAQuery(EntityManager em) {
        super(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata());
    }

此类死锁可能是由从静态初始值设定项引用子类时的典型 bug 引起的。如果您共享其他线程堆栈的详细信息,我们可能会找出哪个线程持有类锁。

那么,为什么线程处于状态呢?RUNNABLE

好吧,这是HotSpot JVM内部的混乱。类初始化过程是在 VM 运行时中实现的,而不是在 Java land 中实现的,并且类锁是在本机获取的。这似乎是线程状态没有改变的原因,但我想这种行为也应该在JVM中修复。


答案 2

Oracle Thread.State 文档指定处于阻塞状态的线程正在等待监视器锁进入同步的块/方法或在调用后重新输入同步的块/方法。它看起来不像阻塞模式下的任何线程。