简体   繁体   English

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

[英]RUNNABLE Thread.State but in Object.wait()

I have extracted a JStack of my container process and got the threads running there with the following distribution grouped by Thread.state : 我已经解压缩了我的容器进程的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)

For the runnable threads I have the following description: 对于可运行的线程,我有以下描述:

"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)
    ...

The number of threads in RUNNABLE state as shown above raises with the time and it seems to be hanging. 如上所示,处于RUNNABLE状态的线程数随时间而增加,并且似乎是悬挂的。 If they suppose to be blocked, shouldn't they be on state BLOCKED? 如果他们认为被阻止,他们不应该处于阻塞状态吗? Or should they be on WAITING state? 或者他们应该处于WAITING状态? Is strange to have RUNNABLE threads but in Object.wait() isn't it? 有RUNNABLE线程但在Object.wait()中是不是很奇怪?

Update 1 更新1

I can see in the documentation: 我可以在文档中看到:

A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor. 处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统的其他资源,例如处理器。

How can I figure out what is the thread waiting for? 我怎样才能弄清楚等待的线程是什么?

This seems like a class initialization deadlock . 这似乎是一个类初始化死锁

JPAQuery constructor is waiting for the initialization of a dependent class, probably JPAProvider : JPAQuery构造函数正在等待依赖类的初始化,可能是JPAProvider

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

Such deadlocks may be caused by a typical bug when a subclass is referenced from a static initializer. 当从静态初始化程序引用子类时,这种死锁可能是由典型的错误引起的。 If you share the details of other thread stacks, we'll likely find out which thread holds the class lock. 如果您共享其他线程堆栈的详细信息,我们可能会找出哪个线程持有类锁。

Why is the thread in RUNNABLE state then? 为什么线程处于RUNNABLE状态呢?

Well, it's a confusion inside HotSpot JVM. 好吧,这是HotSpot JVM内部的混乱。 The class initialization procedure is implemented in VM runtime, not in Java land, and the class lock is grabbed natively. 类初始化过程在VM运行时实现,而不是在Java域中实现,并且类锁是本机获取的。 Seems to be a reason why a thread state has not been changed, but I guess this behavior should be fixed in JVM as well. 似乎是线程状态未被更改的原因,但我想这种行为也应该在JVM中修复。

The Oracle Thread.State documentation specifies that a thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling. Oracle Thread.State文档指定处于阻塞状态的线程正在等待监视器锁定以在调用后输入同步块/方法或重新输入同步块/方法。 It looks like none of the threads in blocking mode. 它看起来像阻塞模式中没有任何线程。

If all the Runnable threads are apparently blocked in database operations, I would suggest using database monitoring/diagnostic tools to explore the reason. 如果在数据库操作中显然阻止了所有Runnable线程,我建议使用数据库监视/诊断工具来探索原因。 After that, possibly investigating your database code to find problems such as uncommitted transactions, mishandled exceptions leading to unclosed resources. 在此之后,可能会调查您的数据库代码以查找诸如未提交的事务,导致未关闭资源的错误处理的异常等问题。

Java thread dumps have probably given you all the information they can at this point - a pointer for where to start looking next. Java线程转储可能已经为您提供了他们此时可以获得的所有信息 - 指示下一步开始查看的位置。

"The number of threads in RUNNABLE state as shown above raises with the time and it seems to be hanging." “如上所示,处于RUNNABLE状态的线程数会随着时间的推移而增加,而且似乎正在悬挂。”

The number of RUNNABLES would rise depending upon the number of threads executing the method "com.mysema.query.jpa.impl.JPAQuery." RUNNABLES的数量将根据执行方法“com.mysema.query.jpa.impl.JPAQuery”的线程数而增加。 at the time this thread dump was taken. 在这个线程转储被采取时。 This method is actually the constructor of JPAQuery class - denoted by "init" . 这个方法实际上是JPAQuery类的构造函数 - 用“init”表示。 You would probably need to investigate the code in the constructor and the subsequent calls to the JPA implementation. 您可能需要调查构造函数中的代码以及后续对JPA实现的调用。

The Object.wait() merely calls Object.wait(0) (zero for no timeout). Object.wait()只调用Object.wait(0) (零表示没有超时)。 The implementation of Object.wait(long) is: Object.wait(long)是:

public final native void wait(long timeout) throws InterruptedException;

All threads that are in a native frame are RUNNABLE , as the JVM does not know (does not "manage", hence it is a "native" frame) the state of the call. 本机帧中的所有线程都是RUNNABLE ,因为JVM不知道(不“管理”,因此它是“本机”帧)调用的状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM