Java RUNNABLE Thread.State但在Object.wait()中

Java RUNNABLE Thread.State但在Object.wait()中,java,multithreading,Java,Multithreading,我已经提取了容器进程的一个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 WAIT

我已经提取了容器进程的一个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)
    ...
“http-bio-8080-exec-55”守护进程prio=10 tid=0x000000002cbaba300 nid=0x642b在Object.wait()中[0x00002ab37ad11000]
java.lang.Thread.State:可运行
请访问com.mysema.query.jpa.impl.JPAQuery。(JPAQuery.java:44)
位于net.mbppcb.cube.repository.TransactionDaoImpl.FindBusinessId(TransactionDaoImpl.java:73)
位于sun.reflect.GeneratedMethodAccessor76.invoke(未知源)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:601)
位于org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
位于org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
在org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:150)上
位于org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
位于org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:172)
位于org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
...
如上所示,处于可运行状态的线程数量随着时间的推移而增加,并且似乎处于挂起状态。如果他们想被封锁,难道他们不应该在国家封锁?或者他们应该处于等待状态?在Object.wait()中有可运行线程是很奇怪的,不是吗

更新1

我可以在文件中看到:

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

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

指定处于阻塞状态的线程正在等待监视器锁进入同步块/方法,或在调用后重新输入同步块/方法。
看起来没有一个线程处于阻塞模式。

如果所有可运行线程在数据库操作中明显被阻塞,我建议使用数据库监视/诊断工具来探究原因。之后,可能会调查数据库代码以发现问题,例如未提交的事务、错误处理的异常导致未关闭的资源

Java线程转储可能已经为您提供了此时所能提供的所有信息——下一步从何处开始查找的指针

“如上所示,处于可运行状态的线程数随时间增加 时间到了,好像要挂了。”

执行此线程转储时,执行方法“com.mysema.query.jpa.impl.JPAQuery”的线程数将增加可运行的线程数。这个方法实际上是JPAQuery类的构造函数——用“init”表示。您可能需要研究构造函数中的代码以及对JPA实现的后续调用。

对象.wait()仅调用对象.wait(0)(零表示无超时)。
Object.wait(long)
的实现是:

public final native void wait(long timeout) throws InterruptedException;
本机框架中的所有线程都是可运行的,因为JVM不知道(不“管理”,因此它是一个“本机”框架)调用的状态。

这似乎是一个错误

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

    public JPAQuery(EntityManager em) {
        super(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata());
    }
当从静态初始值设定项引用子类时,这种死锁可能是由错误引起的。如果您共享其他线程堆栈的详细信息,我们可能会发现哪个线程持有类锁

为什么线程处于
可运行状态


嗯,这在HotSpot JVM中是一个混乱的问题。类初始化过程是在VM运行时实现的,而不是在javaland中实现的,并且类锁是本机抓取的。这似乎是线程状态未更改的原因之一,但我想这种行为也应该在JVM中修复。

对象.wait()
中的线程应该具有
线程.state.WAITING
,而不是
阻塞的
。也就是说,我不知道为什么它可以运行。你是对的,我错了。但这种奇怪的状态可能与我的JVM版本和OS版本有关吗?也许两者的结合有点奇怪?Object.wait()中线程的堆栈跟踪的其余部分是什么?@DennisW线程正在调用
o。wait()
并不像您想象的那样与其状态紧密耦合。当发出事件信号时,线程的状态将从
WAITING
更改为
RUNNABLE
,但线程仍将处于
o.wait()
调用中。然后它将经历其他状态更改:它最终将运行,然后在尝试重新获取锁时可能再次被阻止,然后它将第二次变为
RUNNABLE
,最后它将第二次运行,它将从调用中返回。@Kristofere:刚刚添加了有关StackTrace的附加信息这是一个有效点,不过,如果调用堆栈中的DB驱动程序被查询阻止,我希望调用它,对吗?奇怪的是,这种情况发生在
JPAQuery上。
,让我知道你的想法。当我评论它随时间上升时,这意味着线程将在给定点(JPAQuery的构造函数)停止,并且不会返回到池中,如果我进行更多的线程转储,那么线程将在同一点上。我在mysema上遇到的问题就是这个(类初始化死锁),这是在mysema上打开的票据:谢谢!我在Obje中看到可运行的线程,这让我很恼火