" BLOCKED"之间的区别和" TIMED_WAITING"在java上

时间:2014-09-16 10:08:11

标签: java multithreading

我们的tomcat没有回应任何请求。当我使用“jstack pid”打印堆栈信息时,我得到了以下信息。我发现它在“Thread.sleep(long)”上被阻止了。我认为它应该是“TIMED_WAITING”。为什么呢?

Thread 24836: (state = BLOCKED)
- java.lang.Thread.sleep(long) @bci=0 (Compiled frame; information may be imprecise)
- com.lagou.base.proxy.MasterTemplateContainer.checkMaster(org.springframework.orm.hibernate3.HibernateTemplate) @bci=128, line=221 (Compiled frame)
- com.lagou.base.proxy.MasterTemplateContainer.access$1(com.lagou.base.proxy.MasterTemplateContainer, org.springframework.orm.hibernate3.HibernateTemplate) @bci=2, line=185 (Interpreted frame)
- com.lagou.base.proxy.MasterTemplateContainer$2.run() @bci=8, line=134 (Interpreted frame)
- java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1145 (Interpreted frame)
- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=744 (Interpreted frame)


Thread 24835: (state = BLOCKED)
- java.lang.Thread.sleep(long) @bci=0 (Compiled frame; information may be imprecise)
- com.lagou.base.proxy.MasterTemplateContainer.checkMaster(org.springframework.jdbc.core.JdbcTemplate) @bci=128, line=177 (Compiled frame)
- com.lagou.base.proxy.MasterTemplateContainer.access$0(com.lagou.base.proxy.MasterTemplateContainer, org.springframework.jdbc.core.JdbcTemplate) @bci=2, line=141 (Interpreted frame)
- com.lagou.base.proxy.MasterTemplateContainer$1.run() @bci=8, line=125 (Interpreted frame)
- java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1145 (Interpreted frame)
- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=744 (Interpreted frame)

我的代码:

private void checkMaster(HibernateTemplate hdao) {
    int loopErrors = errorTimes;
    int loopSuccess = successTimes;
    while(true) {
        boolean success = true;
        try {
            if(hdao == null){
                success = false;
                continue;
            }
            success = checkMasterStatusOnce(hdao);//try access database to get the status
        } catch (Exception e1) {
            logger.error("",e1);
            success = false;
        }

    try {
        Thread.sleep(checkInterval);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

中调用该方法
public void check() {
    for (final JdbcTemplate jdao : jdbcTemplates) {
        threadPoolExecutor.execute(new Runnable(){
            public void run() {
                checkMaster(jdao);
            }
        });
    }
}

1 个答案:

答案 0 :(得分:0)

你是对的,方法ThreadThread.sleep的线程状态应为TIMED_WAITING

引用authoritative source

  

public static final Thread.State TIMED_WAITING

     

具有指定等待时间的等待线程的线程状态。由于在指定的正等待时间内调用以下方法之一,线程处于定时等待状态:

     
      
  • Thread.sleep
  •   
  • Object.wait超时
  •   
  • Thread.join超时
  •   
  • LockSupport.parkNanos
  •   
  • LockSupport.parkUntil
  •   

我测试了1.61.8范围内的几个Java版本(Oracle的实现),并且都显示了Thread.sleep内状态为{{1}的报告线程的正确行为}}

考虑the following statement about Thread.sleep()

也很重要
  

......线程不会失去任何监视器的所有权。

因此,由于线程不会丢失监视器的所有权,因此它不会重新获取监视器。所以它不应该在Thread.State.BLOCKED

因此,您要么使用不同的JVM / JRE实现,要么使用修改后的TIMED_WAITING类,可能是在运行时通过Instrumentation进行了修改。在任何一种情况下,您在问题中提供的信息都不足以进一步缩小您的问题。

知道哪个版本的Thread作为输出使用的格式与我得到的格式不同也是有用的。也许这是打印状态错误的工具......