javaandroidperformancethread-dumpthread-state

What does the java thread's state really mean?


I am learning the tool in Android Studio, get thread dump, as follow:

get thread dump

I notice the different state of every thread like this,

enter image description here

I can see there are runnable,sleeping,waiting. And I deep into the thread stack, most thread stack like this,

"<61> RxComputationScheduler-3@830064517520" daemon prio=5 waiting
    java.lang.Thread.State: WAITING
        at java.lang.Object.wait(Object.java:-1)
        at java.lang.Thread.parkFor(Thread.java:1205)
        at sun.misc.Unsafe.park(Unsafe.java:325)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2017)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1050)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:778)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1097)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:841)

I am confused that they do all halt at Object.wait, however the state of thread can be runnable,sleeping,waiting?

Here is the other state thread's stack.

RUNNABLE

<53> RxSchedulerPurge-1@830057651944" daemon prio=5 runnable
  java.lang.Thread.State: RUNNABLE
      at java.lang.Object.wait(Object.java:-1)
      at java.lang.Thread.parkFor(Thread.java:1205)
      at sun.misc.Unsafe.park(Unsafe.java:325)
      at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:197)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2056)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1062)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:778)
      at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1097)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
      at java.lang.Thread.run(Thread.java:841)</code>

TIMED_WAITING

<58> RxScheduledExecutorPool-2@830064740632" daemon prio=5 sleeping
  java.lang.Thread.State: TIMED_WAITING
      at java.lang.Object.wait(Object.java:-1)
      at java.lang.Thread.parkFor(Thread.java:1205)
      at sun.misc.Unsafe.park(Unsafe.java:325)
      at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:197)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2056)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1062)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:778)
      at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1097)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
      at java.lang.Thread.run(Thread.java:841)

Solution

  • New means the thread is in new state if you create an instance of Thread class but before the invocation of start() method:

    Thread t = new Thread(...); // t is New
    

    Runnable means the thread is in runnable state after invocation of start() method. Basically:

    t.start(); // t is Runnable
    

    Running is the "sub-state" of Runnable: the thread is in running state if the thread scheduler has selected it. You can't do anything with it explicitly, meaning you call start() and then just wait.

    Ready is another "sub-state" of Runnable: the thread is eligible for running and waits for the thread scheduler to select it.

    Blocked means the state when the thread is still alive, but is currently not eligible to run. This happens, for example, when one thread comes across a synchronized block, which is processed by another thread. In this case the first thread becomes blocked.

    Waiting is the state when your thread is neither blocked nor ready. This usually happens when you call wait() or join() on a thread.

    Thread t1 = new Thread(); // t1 is New
    Thread t2 = new Thread(); // t2 is New
    t1.start(); // t1 becomes Runnable
    t2.start(); // t2 becomes Runnable
    t1.join(); // t2 becomes Waiting, because t1 is processed until it terminates
    

    There is also a state called Timed Waiting, which is almost the same thing, but is caused by calling sleep(). If you call wait(timeout) or join(timeout), the thread also gets timed waiting state.

    Thread t = new Thread(); // t is New
    t.start(); // t is Runnable
    t.sleep(4000); // t get state of Timed Waiting for 4 seconds
    

    Terminated is a thread in terminated or dead state when it's run() method exits.

    I think I covered it all :) Here is an image to help you understand it more clearly:

    Thread Life Cycle Java

    As JoxTraex requested, here're sources I read before posting:

    1. https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html
    2. javarush.ru
    3. http://www.uml-diagrams.org/examples/java-6-thread-state-machine-diagram-example.html
    4. http://www.journaldev.com/1044/thread-life-cycle-in-java-thread-states-in-java

    It's just a matter of good googling skill, really...