I have a performance issue (in a complex Scala code using parallel collections and futures). I have used JFR to check more details and I can see the issue manifests itself as a thread waiting on a monitor object (the thread seems to be waiting in java.util.concurrent.ForkJoinTask#internalWait by calling a wait method of the ForkJoinTask). I would like to know which thread holds this monitor object (and from what function / call-stack the monitor was entered). JFR shows me some kind of an address for the monitor, but I did not find a way to search / filter by this address.
Is there some view in the JMC, a plugin, or some other way how to check who and when is locking and releasing given monitor?
The problem is, a monitor object being waited on, is not technically held by any thread. Such monitor has no "owner". In general, you can't know beforehand, which thread is in charge of calling notify, as it can be any thread, or no thread at all.
However, if a monitor has already been notified, there will be a JFR event containing the information about Notifier Thread. You can see it on your screenshot: the monitor was notified by scala-execution-context-global-54 thread.
Related
Trying to understand wait() and notify(). I know when thread A went to wait() it will be waked up by notify() from other thread.
But what will happens if threads A,B,C went to wait() in represented order? Who will be waked up by notify()? According to my experiments A thread will be waked up at first. I'm right?
Does it means that system knows in which order threads went to wait() ?
From the documentation for notify(), emphasis mine:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
Some other APIs, such as Semaphore, have a concept of "fairness", where you can ensure that threads do proceed in the order in which they blocked.
Section 17.2.2 Notification of Java Language Specification:
There is no guarantee about which thread in the wait set is selected.
So, observed behavior is not guaranteed and should not be relied upon.
No, the VM does not know in which order the threads were put in Waiting state.
When you call notify(), one of them will be back to Alive/Runnable state and there is no way to know which one the VM will choose.
Sometimes they can run in the order they were put in Waiting state, but the specification does not guarantee that. So in a different VMs you can have a completely different results or even in the same VM, if you run the code multiple times.
No, there is no guarantee about the order. The javadoc of the notify method is pretty clear on this:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
There's no such an order. Either thread has an equal opportunity to get into runnable state. Actually JVM/OS can see them only as a set of waiting threads, they don't know any order.
In terms of your experiment, to get into a fair conclusion, actually you have to perform it for a huge number of times.
In threads, you can expect an order (FIFO), only if you are using something like a strong Semaphore. Then these threads are put into a waiting queue and fist comer would be first served.
Let's say that i have 10 active threads and only 3 resources (of something)
while the first three threads got the resources i want all other thread that try to get the resource to wait but that the wake up or notify will be in f.i.f.o order i mean that the first thread that got the waiting will be the first to wake up.
thank you all.
I think this link explains it quite well: https://www.safaribooksonline.com/library/view/java-threads-second/1565924185/ch04s03.html
When using notify it is impossible to decide or determine in advance which thread will be allowed to execute. I see 2 solutions to this:
Use notifyAll() and let each thread check for itself whether whose turn it is (e.g. by using a synchronised FIFO queue)
Use the method described in the link: let each thread wait on a different object and use 1 thread that has as it's sole purpose to notify the correct object. This seems like the best solution to me.
Java generally doesn't decide these things however if you use a fair lock e.g.
Lock lock = new ReentrantLock(true);
then those threads will acquire the lock in the order they were attempted. This works by disregarding the order thread would be notified and ensuring a lock which is not taken unless the thread is next on the FIFO queue.
As per the javadoc notify Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
I want to know how notify achieve this behavior. On many sites I read it sends a signal but What does signal means here?
Does notify sends a signal directly to first waiting thread or it sends a signal to thread scheduler?
It does not send it to the first thread, but to any waiting thread (but only one thread).
You should read the javadoc more carefully.
Signal is also possibly a bad name for it, 'notify' is better. The actual implementation of the mechanism is transparent to the Java programmer, and the technical implementation should not be necessary for you to know.... unless you have an interest in Java internals, and then I suggest you inspect the OpenJDK source code.
I'd like to check if my reasoning is correct.
First of all, I should provide a few details about the problem I'm trying to solve. A thread (part of a program) does the following things:
it starts
it calls Thread.sleep (20ms)
it calls getIn() method
it tries to get a lock (lock.lock())
if successfully gets the lock it calls Thread.sleep (100ms)
if the lock is not available it calls waitingCond.await()
after calling Thread.sleep (100ms) it calls lock.unlock()
it calls another method getOut()
it terminates (thread.join())
Given that, the following is my guessing about the thread state:
READY TO RUN state
TIMED WAITING state
WAITING state
WAITING state
BLOCKED state
WAITING state
WAITING state
TERMINATED state
Thanks
First of all, the state you describe with READY TO RUN is actually RUNNABLE. For my bachelor thesis I had created a transition graph showing the different thread states and when they ought to change. You haven't described the semantics of getIn(), so I guess it is just a random method.
If the thread is executing code, for instance on of your methods getIn() or getOut() it is RUNNABLE and not WAITING. BLOCKED is actually only a very short transition state, which is always entered when a thread tries to claim a lock. If the lock is not available the thread keeps being blocked and cannot execute another action as you imply in step 6. Also it cannot invoke a method after calling Thread.sleep() it has to wait, until the time is elapsed.
I would correct it the following way:
RUNNABLE
TIMED WAITING
RUNNABLE
BLOCKED
TIMED WAITING
BLOCKED
RUNNABLE
TERMINATED
Disclaimer: There is no guarantee for the transitions. It might even be, that a JVM vendor decides to implement the underlying mechanics in another way, for instance it could implementing blocking by spin-waiting.
If you want to dive deeper into this topic use a Profiler to find out the states of your thread. I have written one of my own to detect those states: Java Concurrency Profiler, but there are others out there as well, for instance VisualVM or YourKit.
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