Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference between "BLOCKED" and "TIMED_WAITING" on java

Our tomcat didn't reponse any request. When I used "jstack pid" to print stack info, I got the following information. I find it was blocked on "Thread.sleep(long)". I think it should be the "TIMED_WAITING". Why?

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)

My code:

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();
    }
}
}

the method is invoked in

public void check() {
    for (final JdbcTemplate jdao : jdbcTemplates) {
        threadPoolExecutor.execute(new Runnable(){
            public void run() {
                checkMaster(jdao);
            }
        });
    }
}
like image 928
soul Avatar asked May 14 '26 02:05

soul


1 Answers

You’re right, the thread state for a Thread inside the method Thread.sleep should be TIMED_WAITING.

To cite the authoritative source:

public static final Thread.State TIMED_WAITING

Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:

  • Thread.sleep
  • Object.wait with timeout
  • Thread.join with timeout
  • LockSupport.parkNanos
  • LockSupport.parkUntil

I tested several Java versions (Oracle’s implementation) in the range 1.6 to 1.8, inclusive, and all show the correct behavior of reporting threads inside Thread.sleep with the state TIMED_WAITING.

It’s also important to consider the following statement about Thread.sleep():

… The thread does not lose ownership of any monitors.

So, since the thread does not lose ownership of monitors, it won’t reacquire monitors. So it shouldn’t be in Thread.State.BLOCKED.

So either you are using a different JVM/JRE implementation or a modified Thread class, maybe it has been modified via Instrumentation at runtime. In either case, the information you have given in your question are not enough to narrow your problem further.

It would be useful as well to know which version of jstack you have used as the output has a different format than I got. Maybe it’s the tool which prints the state wrong…

like image 86
Holger Avatar answered May 16 '26 16:05

Holger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!