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

时间:2015-02-20 14:44:38

标签: 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    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状态的线程数会随着时间的推移而增加,而且似乎是挂起的。如果他们认为被阻止,他们不应该处于阻塞状态吗?或者他们应该处于WAITING状态?拥有RUNNABLE线程但在Object.wait()中是不是很奇怪?

更新1

我可以在文档中看到:

  

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

我怎样才能弄清楚等待的线程是什么?

5 个答案:

答案 0 :(得分:20)

这似乎是class initialization deadlock

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

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

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

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:1)

如果在数据库操作中显然阻止了所有Runnable线程,我建议使用数据库监视/诊断工具来探索原因。之后,可能会调查您的数据库代码,以查找未提交的事务,导致未关闭资源的错误处理异常等问题。

Java线程转储可能已经为您提供了他们此时可以获得的所有信息 - 指示下一步开始查看的位置。

答案 3 :(得分:0)

  

&#34;如上所示处于RUNNABLE状态的线程数随之增加   时间,似乎是悬挂。&#34;

RUNNABLES的数量会增加,具体取决于执行方法的线程数&#34; com.mysema.query.jpa.impl.JPAQuery。&#34;在这个线程转储被采取时。此方法实际上是JPAQuery类的构造函数 - 由&#34; init&#34; 表示。您可能需要调查构造函数中的代码以及后续对JPA实现的调用。

答案 4 :(得分:0)

Object.wait()只调用Object.wait(0)(零没有超时)。 Object.wait(long)的实施是:

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

本机框架中的所有线程都是RUNNABLE,因为JVM不知道(不管理&#34;因此它是&#34;本机&#34;帧)电话的状态。