Can someone please explain me the difference between Sleeping, Wait, Park, and Monitor thread states in VisualVM.
This is what I have found:
Running: thread is still running.
Sleeping: thread is sleeping (method yield() was called on the thread object)
Wait: thread was blocked by a mutex or a barrier, and is waiting for another thread to release the lock
Park: parked threads are suspended until they are given a permit. Unparking a thread is usually done by calling method unpark() on the thread object
Monitor: threads are waiting on a condition to become true to resume execution
What I am unable to understand is the state Park, what actually suspends the thread? How do I detect in the code what has made the thread suspend its execution?
Can someone please guide me in this regard.
Thanks.
I found a very nice diagram which pretty much describes all you need/want to know.
New
The thread is in new state if you create an instance of Thread class but before the invocation of start() method.
Runnable
The thread is in runnable state after invocation of start() method, but the thread scheduler has not selected it to be the running thread.
Running
The thread is in running state if the thread scheduler has selected it.
Timed waiting
Timed waiting is a thread state for a thread waiting 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(sleeptime)
Object.wait(timeout)
Thread.join(timeout)
LockSupport.parkNanos(timeout)
LockSupport.parkUntil(timeout)
Non-Runnable (Blocked)
This is the state when the thread is still alive, but is currently not eligible to run.
Terminated
A thread is in terminated or dead state when its run() method exits.
Hopefully this answers your question :).
Parking:
Disables the current thread for thread scheduling purposes unless the
permit is available.
Threads are being parked or suspended if you like to call it this way because it does not have a permission to execute. Once permission is granted the thread will be unparked and execute.
Permits of LockSupport are associated with threads (i.e. permit is given to a particular thread) and doesn't accumulate (i.e. there can be only one permit per thread, when thread consumes the permit, it disappears).
VisualVM maps the Java thread state (as described in #Maciej's answer) to the state presented in its UI as follows:
BLOCKED -> Monitor
RUNNABLE -> Running
WAITING/TIMED_WAITING -> Sleeping/Park/Wait (see below)
TERMINATED/NEW -> Zombie
Sleeping and Park are specific cases of (timed) waiting:
Sleeping: specifically waiting in Thread.sleep().
Park: specifically waiting in sun.misc.Unsafe.park() (presumably via LockSupport).
(The mapping is performed in ThreadMXBeanDataManager.java.)
A brief (and non-authoritative) discussion of Java thread state can be found here.
EDITED TO ADD:
It's also worth noting that threads blocking in calls to native methods appear in the JVM as RUNNABLE, and hence are reported by VisualVM as Running (and as consuming 100% CPU).
Related
There seems to be a discrepancy between SO consensus and nearly every Java thread state diagram on the Internet; specifically, regarding thread state transition from WAITING after notify() or notifyAll() is invoked...
WAITING never goes directly to RUNNABLE
The thread is WAITING until it is notified...Then it becomes BLOCKED...
Once this thread is notified, it will not be runnable...This is..Blocked State.
So the concensus on SO is: a thread transitions from WAITING to BLOCKED after invoking notify() or notifyAll(); diagram below illustrates this transition in green.
Question
Why do most state diagrams on the web illustrate the transition from WAITING to RUNNABLE, not BLOCKED? Depiction in red shows the incorrect transition; am I missing something?
Any diagram that shows a notify invocation bringing a thread from WAITING to RUNNABLE is wrong (or is using an unclarified shortcut). Once a thread gets awoken from a notify (or even from a spurious wakeup) it needs to relock the monitor of the object on which it was waiting. This is the BLOCKED state.
Thread state for a thread blocked waiting for a monitor lock. 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 Object.wait.
This is explained in the javadoc of Object#notify():
The awakened thread will not be able to proceed until the current
thread relinquishes the lock on this object.
and Object#wait()
The thread then waits until it can re-obtain ownership of the monitor
and resumes execution.
A thread is in WAITING state goes in BLOCK state,until it acquires monitor by notify and become RUNNABLE.
Same applies for TIMEDWAITING,it goes in BLOCK state,if monitor is hold by some other thread,even though specified time has passed.(your diagram need to be corrected)
I am focusing on the problem recently.
as the Oracle document Thread.State says we can use LockSupport.park() to put the current thread into 'WAITING' or 'TIMED_WAITING' state.
so when you try the LockSupport.unpark(), the specified thread will return to 'RUNNABLE' from 'WAITING'/'TIMED_WAITING'. (I am not sure whether it will go through the 'BLOCKED' state)
It is worth to mention that is also true for Thread.interrupt() method during WAITING state while in lock.wait() method.
Thread.interrupt() method will firstly make WAITING thread BLOCKED with isInterrupted flag set to true, and only after reacquiring lock interrupted thread will be able to throw InterruptedException (that is obvious, as it cannot handle exception, by that continuing execution without having exclusive lock before). (example here)
Simply to say
Always WAITING -> BLOCKED to be able again compete for the lock, and after that to acquire it eventually and run its' code RUNNABLE.
What is the difference between a parked thread and a waiting thread in java ? I've a jboss core dump and analysing it is showing a lot of parked threads.
Look at Javadoc the park() method:
Disables the current thread for thread scheduling purposes unless the
permit is available. If the permit is available then it is consumed
and the call returns immediately; otherwise the current thread becomes
disabled for thread scheduling purposes and lies dormant until one of
three things happens:
Some other thread invokes unpark with the current thread as the
target; or Some other thread interrupts the current thread; or The
call spuriously (that is, for no reason) returns. This method does not
report which of these caused the method to return. Callers should
re-check the conditions which caused the thread to park in the first
place. Callers may also determine, for example, the interrupt status
of the thread upon return.
So a parked thread is a thread blocked using LockSupport.park().
Both park() and wait() will result in a disabled thread. Making a disabled thread active again depends on how it was disabled.
A thread that has been disabled by calling LockSupport.park() will remain disabled until:
some other thread calls unpark(), or
some other thread calls interrupt(), or
"the call spuriously (that is, for no reason) returns"
A thread that has been disabled by calling Object's wait() – which is equivalent to calling wait(0) – will remain disabled until:
some other thread calls notify() or notifyAll(), or
some other thread calls interrupt() on the disabled thread
In Java, a parked thread by calling LockSupport.park() method is a waiting thread ( in the Thread.state.WAITING ).
See the Java Doc for Thread.state.WAITING.
There are 3 ways to cause a thread to be in the WAITING status:
Object.wait with no timeout
Thread.join with no timeout
LockSupport.park
A thread in the waiting state is waiting for another thread to perform a particular action.
For example, a thread that has called Object.wait() on an object is waiting for another thread to call Object.notify() or Object.notifyAll() on that object. A thread that has called Thread.join() is waiting for a specified thread to terminate.
Parking means suspending execution until permit is available. Permit means a permission to continue execution.
A thread can suspend its execution until permit is available. When permit is available, the parked thread consumes it and exits a park() method.
LockSupport - class takes facility basic thread blocking primitives for creating locks and other synchronization classes.
Method park() disables the current thread for thread scheduling purposes unless the permit is available.
unpark(Thread thread) makes available the permit for the given thread, if it was not already available.
Use it like:
finally {
LockSupport.unpark(thread);
}
I've read many docs about thread states, some of them tells that there is two different states: blocked (before synchronized) and wait (if calls wait), some others are telling that there is only one state: wait. Moreover, some docs telling that you should call notify() for every wait() and if you don't then threads waiting() will never be eligible for execution even if monitor is unlocked.
From you last sentence I see you don't fully understand the difference between synchronized and wait()/notify().
Basically, monitor has lock and condition. It's almost orthogonal concepts.
When thread enters a synchronized block, it acquires a lock. When thread leaves that block, it releases a lock. Only one thread can have a lock on a particular monitor.
When thread having a lock calls wait(), it releases a lock and starts waiting on its condition. When thread having a lock calls notify(), one of the threads (all threads in the case of notifyAll()) waiting on the condition becomes eligible for execution (and starts waiting to acquire a lock, since notifying thread still has it).
So, waiting to acquire a lock (Thread.State.BLOCKED) and waiting on the monitor's condition (Thread.State.WAITING) are different and independent states.
This behaviour becames more clear if you look at Lock class - it implements the same synchronization primitives as synchronized block (with some extensions), but provides clear distinction between locks and conditions.
There are two different states BLOCKED and WAITING.
The part about waiting forever if no one notifies (or interrupts) you is true.
Standard doc is here
When a thread calls Object.wait
method, it releases this acquired
monitor and is put into WAITING (or
TIMED_WAITING if we call the timeout
versions of the wait method) state.
Now when the thread is notified either
by notify() or by notifyAll() call on
the same object then the waiting state
of the thread ends and the thread
starts attempting to regain all the
monitors which it had acquired at the
time of wait call. At one time there
may be several threads trying to
regain (or maybe gain for the first
time) their monitors. If more than one
threads attempt to acquire the monitor
of a particular object then only one
thread (selected by the JVM scheduler)
is granted the monitor and all other
threads are put into BLOCKED state.
In Java's perspective (Thread.State), there are two different states: BLOCKED and WAITING . When a thread synchronizes on a Object, it is in BLOCKED state. After a thread executes wait, it is in WAITING state.
On Linux platform, Java thread is OS native thread. The OS thread state for both BLOCKED and WAITING states is Interruptible sleep. When being checked with ps, the state for both BLOCKED and WAITING threads is "Sl+".
What is the Thread.State of a thread after Thread.yield() ? Is it a Thread.State.WAITING? Thanks.
No, the thread will still be in the RUNNABLE state. Note that RUNNABLE signifies that a thread is available to be run and may be either currently running or waiting its turn. Thread.STATE does not distinguish between a thread that is currently executing and a thread that is ready to run, they are both RUNNABLE.
A thread will only enter the WAITING state when either wait(), join() or LockSupport.park() has been called.
By calling Thread.yield() method the currently running thread is voluntarily giving up its slice of CPU time. This thread then goes from running back into a ready state.
The documentation of selectorObj.select() method states
This method performs a blocking
selection operation. It returns only
after at least one channel is
selected, this selector's wakeup
method is invoked, or the current
thread is interrupted, whichever comes
first.
I understand the documentation
The thread that is blocked by select method, shouldn't be waiting? When I run profiler I see the thread is in run mode instead of wait state.
Although, I accept that, it is not mentioned that the thread should be in wait state, but my assumption is that till the signal dispatcher thread provides some input regarding any activity on channel registered with selector; the thread should be in wait state.
Please provide me some help as to why my assumption could be wrong.
When the thread is blocked in an I/O call, it is still running as far as Java thread is concerned.
Most profilers simply show thread state, which is defined as,
NEW A thread that has not yet started is in this state.
RUNNABLE A thread executing in the
Java virtual machine is in this
state.
BLOCKED A thread that is blocked
waiting for a monitor lock is in this
state.
WAITING A thread that is waiting
indefinitely for another thread to
perform a particular action is in
this state.
TIMED_WAITING A thread that is
waiting for another thread to perform
an action for up to a specified
waiting time is in this state.
TERMINATED A thread that has exited
is in this state.
As you can see, thread's WAITING/BLOCKED state has nothing to do with I/O.
Normally the select operation invokes the poll(...) system function.
select() provides the kernel with a list of file descriptors that it needs to monitor for read/write/error conditions as well as a timeout value. The kernel registers the process/thread with the associated channel's select function and puts the process/thread to sleep. Once the associated channel is ready or a timer has been expired, the kernel wakes up the registered process/thread. Note that this thread is the kernel thread and not the java application thread.
I do not see a reason for the thread doing select to be in WAIT state (Unless the implementation of the Selector returned by the Selector provider explicitly did a wait in the select() function).
It depends on the profiler. JProfiler shows the time when the selector thread is blocked on Selector.select() as "Network I/O". So, the best way to interpret the blocked Selector.select() as "Waiting for data".
Hope this helps.
Regards,
Slava Imeshev
Cacheonix In-Memory Data Grid