JLS 17.2.4:
If a thread is both notified and interrupted while waiting, it may
either:
[...]
Could you give an example of thread which is both interrupted and notified while waiting? I cannot understand how it is even possible because when we call
Thred.interrupt()
or
obj.notify()
the thread will be removed from the wait set. Since further call doesn't relate to a waiting thread. It has been removed from wait set yet.
Consider this code:
synchronized(obj) {
obj.notify();
threadWatingOnObj.interrupt();
}
Before the thread executing the above code releases the lock, no notified thread will be able to proceed. Therefore, when control returns to such a thread from its obj.wait() call, it will have been both notified and interrupted.
That looks like a question from an exam. You're supposed to fill in the blank, right?
I think the question is poorly thought out because "interrupted" is a state that a thread can be in, and "waiting" is a state that a thread can be in, but "notified" is not a state.
If a thread calls wait() when it is already in the interrupted state, then the wait() call will return an exception. Likewise, if a thread is in the waiting state when it becomes interrupted, then the wait() call will return an exception in that case too.
Maybe when they say "a thread is both notified and interrupted", they mean that the thread was waiting, and it was notified, and then an interrupt was delivered while the thread still was in the wait() call, trying to re-acquire the mutex.
I have no inside knowledge of what happens in that case, but based on the Javadoc for Object.wait(), I would expect the wait() call to return normally after it acquires the mutex.
Related
I read in a Java textbook the following pertaining to multi-threading.
For a thread to call wait() or notify(), the thread has to be the owner of the lock for that object. When
the thread waits, it temporarily releases the lock for other threads to use, but it will need
it again to continue execution.
I'm confused about what is meant by the clause
When the thread waits, it temporarily releases the lock for other
threads to use
I don't get what that clause is talking about. Is it saying that when the wait() method is called it is actually releasing the lock before the wait() returns (i.e. this happens without caller knowing)? Or is it just alluding to wait(timeout) releasing the lock when the timeout elapses? If it is the former why would it release the lock before notify()? This seems like a vague and poorly explained statement.
For a thread to call wait() or notify(), the thread has to be the owner of the lock for that object.
Otherwise, a runtime error occur and the rest of code is not executed.
When the thread waits, it temporarily releases the lock for other threads to use
In more details, call to wait() does the following:
the lock is released
current thread is registered as waiting in the monitor
processor switches to some other thread ready for execution
Then, some thread calls notify() or notifyAll(), which causes one or all threads which are registered as waiting at this monitor to be moved from the wait set to the ready set, waiting for a free processor to execute.
but it will need it again to continue execution.
This means the execution of the thread is continued with executing synchronized statement to regain the lock. After the lock is aquired, then the wait() method returns. wait(timeout) differs in that except for notify() or notifyAll(), it also can return upon the timeout.
In sum, you need to understand how a thread switches between following 4 states:
running on a processor
blocked on synchronized statement
waiting for notification
ready to execute and waiting for a free processor
When a thread calls wait, the thread releases the lock right away and then goes dormant until either the timeout expires, if any, or until it receives a notification, which occurs when another thread acquires the same lock that the waiting thread gave up and calls notify on it (also the scheduler has to pick the waiting thread from among any other waiting threads; calling notify doesn’t notify a given thread, it tells the scheduler to pick a thread from a given lock’s wait set to notify).
Once the thread is woken up by a notify, it has to reacquire the lock in order to leave the wait method, because the thread is still inside of a synchronized method or block. That is what the quote means when it says the thread will need the lock to resume execution.
When a thread calls wait(), it's temporarily releasing the monitor (lock) of the object until it receives a notification from another thread. This way, a thread can willingly give control (that it has, in the first place) of the object's monitor to another thread. Take a look at the docs:
The invocation of wait() does not return until another thread has
issued a notification that some special event may have occurred —
though not necessarily the event this thread is waiting for (so always
invoke wait() inside a loop that tests for the condition being
waited for).
...
When wait() is invoked, the thread releases the lock and suspends
execution. At some future time, another thread will acquire the same
lock and invoke Object.notifyAll, informing all threads waiting on
that lock that something important has happened.
synchronized (Foo.class) {
while (someCondition) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
It seems that this thread both wakes when some other thread call interrupt() or notify() on this thread. Are there any differences between the two?
--EDIT--
I know one is for notifying an object, the other interrupts a thread. But both of these lead to the same consequence, that is, this thread is waken up, so what I want to ask is how these 2 situations' consequences are different from each other.
When a thread calls notify on some monitor, it wakes up a single thread that's waiting on that monitor, but which thread gets woken is decided by the scheduler. (Alternatively a thread can call notifyAll, which wakes up all the threads waiting for that monitor, then they all contend for the monitor, then the losers go back to waiting.) That's why the target of the call is different, the notification is made to the monitor, which tells the scheduler to pick a thread to wake up.
Unlike notify, interruption targets a specific thread. And interruption does not require that the interrupted thread be waiting on a monitor. For a thread to call wait on a monitor it has to have acquired that monitor first, then wait releases that monitor until the thread is done waiting or is interrupted.
Oracle's recommendation is to use interruption only for cancellation. Also the classes in java.util.concurrent are designed to use interrupt for cancellation.
In your example interruption won't be very effective, because control doesn't leave the while loop, the thread still has to check the condition it's waiting on, and there's no check in the while loop condition for whether the interrupt flag is set. It's likely the thread that's interrupted will go right back to waiting.
In order to make this code quit once it's interrupted, rather then return to waiting, add a check for the interrupted flag status to the loop condition, and have the catch block set the interrupt flag (which gets reset when the exception is thrown):
synchronized (Foo.class) {
while (someCondition && !Thread.currentThread().isInterrupted()) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Basically, you are not looking for a text book difference but difference in their uses cases.
As folks have already pointed out, waking up the thread is not the only consequence but calling t1.interrupt() from Thread t2 for t1 will cause an InterruptedException in thread t1 and that is a big difference between Object.notify() and Thread.interrupt().
You should understand that its method Object.wait() which throws checked InterruptedException and forces you to handle it. Object.wait.
InterruptedException - if any thread interrupted the current thread
before or while the current thread was waiting for a notification. The
interrupted status of the current thread is cleared when this
exception is thrown.
Then you should consult this question to get an idea about handling this exception.
Difference between the two lies in the fact that one is for inter thread communication for usual logical programing stuff ( wait & notify ) and other one ( interrupt) is for preemptive thread cancellation / termination even in cases of blocking operations. You have to note that Java doesn't provide any mechanism to preemptively cancel a thread so you have to use interrupt mechanism for that purpose ( Obviously, if that is needed in your case. You might very well ignore this Exception if not applicable in your case).
Java doesn't restrict your actions after InterruptedException and you can do anything you want but using it for things other than implementing Thread Cancellation Policy is not advised. Thread Cancellation Policy is often ignored and less discussed area when programmers write multi threaded programs and that is why you might be finding it difficult to understand the use case.
What does an API method like BlockingQueue.put(..) is trying to tell you by throwing InterruptedException is that even its blocking operation can be preemptively terminated. Its not necessary that all blocking API methods will provide you that facility.
Cancellation/Termination of a thread using Thread.interrupt() is not a forceful but cooperative mechanism and is just a request not an order.
Your use of e.printStackTrace(); is strongly discouraged since this is usually not an error, if intention is to log it as an error.
Hope it helps !!
Wait method is used to suspend a current thread on an object.
Wait method is not from thread class but from java.lang.Object
Notify method is used to wake the thread waiting on the object.
Notify method is not from thread class but from java.lang.Object.
Interrupt method is used to to indicate the current thread that is
should stop current job execution and can start other job.
Interrupt method is from thread class.
Let see the real life example:
Consider Telephone as Object , Person as Thread.
Suppose for instance A person is using Telephone and B person also wants to use the telephone but as A person i.e (Thread 1) is busy using it unless the work is done acquires a lock on telephone Object now B i.e(Thread 2) tries to use Telephone but as A has acquired lock on it B it goes into wait state until lock is released.
If Telephone object calls wait method it will restrict current thread
which want to use Telephone and it will go into wait state.
If Telephone object calls notify it will signal the thread waiting on
it to acquire lock and proceed with the intended work.
If Person A(Thread 1) is using Telephone object and is in some task
but interrupt method is called then A will be signaled to stop with
current task and may need to do some other task assigned.
I have a simple program which I am finding very confusing. The code snippet is as follows:
class Processor{
public void produce() Throws InterruptedException{
synchronized(this){
System.out.println("Producer Running...");
wait();
System.out.println("Resumed");
}
}
public void consume() Throws InterruptedException{
synchronized(this){
Thread.Sleep(2000);
System.out.println("Consumer Running... Press return key to return");
scan.nextLine();
notify();
Thread.sleep(5000);
}
}
Now my question is that , when we call wait() in the "produce" method the execution is immediately transferred to the "consume" method. (produce and consume are executed in separate threads). But when the notify(); is called in the "consume " method ,the execution does not immediately transfer. It waits for Thread.sleep(5000) to complete . why is this so ?
Well, the reason is quite simple.
When a thread calls wait() on certain object it goes into a waiting state and it stops executing (it is removed from scheduling). When waiting a thread releases all the monitors it has taken (and it needs to regain them after waking up)
When a thread calls notify() on certain object it wakes up another thread waiting over it, but it does not go into a waiting state itself, so it keeps running.
After your producer thread calls notify it keeps running and performing a five seconds sleep. While sleeping a thread retains all monitors that it has taken (you are inside a synchronized(this) block hence you have a monitor for "this" object). Scheduler cannot run the consumer thread that was just notified since it needs to readquire the monitor before resuming, and it wont be freed until your producer thread stops sleeping and gets out of the synchronized block
Although you seem to be missing some code needed for me to explain completely accurately, I'll do my best to provide an explanation that would be applicable even if my guess was incorrect.
wait() and notify() are methods called on a mutex object -- in this case, this.
wait() causes the currently executing thread to pause and give up that mutex (I think it's just the mutex that wait() is called on, could be all of them. Not sure), after which another thread can acquire the mutex and start executing. This is why you observe an immediate transfer of control when wait() is executed.
When notify() is called on a mutex, a thread waiting on that mutex wakes up and attempts to acquire the lock. However, it cannot do so until the lock is available -- in this case, until the lock (this) is released by the thread that calls notify() (the consumer thread). The mutex is only released once the consumer thread exits from the synchronized block, which is after the Thread.sleep(5000); call in your code. sleep() does not release any mutexes that the current thread has acquired, so the first thread has to wait until the second has finished sleeping and exited the synchronized block.
That is why wait() transfers control immediately, while notify() (in this case) has the currently executing thread finish its method before the formerly waiting thread can continue execution.
Assuming that you are calling both methods using the same object from difference threads.
If you want to don't wait 5000 miliseconds, use wait(5000) instead of Thread.sleep(5000).
The notify method, take one (random) previously waiting thread, that is waiting to acquire the lock (of an object) that the running/current thread has taken before, and mark it to resume as soon the current thread release the lock.
In your this case, it will release the lock and soon the Thread.sleep(5000) finish and leave the synchronized block.
Be aware, if you call produces or consume with diferents objects things will go totally diferent. I strongly suggest to read this article.
Hope it helps! As the good answers below!
The reason is that Thread.sleep(5000L) does not release the lock on the object's monitor while it's waiting, contrary to wait(5000L). This is specified in the Javadoc for Thread.sleep() :
... The thread does not lose ownership of any monitors.
Whereas the javadoc for Object.wait() specifies:
... This method causes the current thread (call it T) to place itself
in the wait set for this object and then to relinquish any and all
synchronization claims on this object...
When a thread calls wait() it is blocked and waits for some notify.
But I want to know what happens with a thread that calls notify(). The current thread is blocked, and returns its execution at the notify point ?
Nothing happens to the current thread that calls notify(), it continues to run until it's natural end.
The wait() and notify() methods must be called within a synchronized context. As soon as the synchronized block that contains the notify() call finishes, the lock is then available and the block containing the wait() call in another thread can then continue.
Calling notify simply moves the waiting thread back into the runnable thread pool. That thread can then continue as soon as the lock is available.
Notify doesn't put current thread to sleep, only wakes up other threads that have waited on the same mutex
Notify doesn't block the executing thread and both the notifier and the waiter happily execute concurrently after that. Notify notifies one of the waiters at random, if you have more than one thread waiting and you want to wake them all you need to use notifyAll. Note that as all thread will still be in a critical section they will be marked active but will exit the critical block one at a time.
Notify doesn't block even if there are no waiting threads.
Note that this only represent the state of the thread: both threads will be active but actual dispatching of instruction depends: if you have more thread than cpu one of them will wait for its timeslice on the cpu.
wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ).
notify() wakes up the first thread that called wait() on the same object.
Under ideal condition notify() is called when thread completes its execution to go back again to calling thread.
But if used before completion then the thread will continue its normal execution until reaches natural end.
According to Java thread state info calling wait() will result a thread to go in BLOCKED state. However this piece of code will result (after being called) in a Thread in WAITING State.
class bThread extends Thread {
public synchronized void run() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Have I got something wrong? Can anybody explain this behaviour to me?
Any help would be appreciated!
The thread is WAITING until it is notified. Then it becomes BLOCKED trying to reenter the synchronized region until all other threads have left.
Relevant parts from the link you posted (about WAITING):
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.
and (about BLOCKED):
A thread in the blocked state is waiting for a monitor lock to [...] reenter a synchronized block/method after calling Object.wait.
The last part occurs when the thread tries to return from wait(), but not until then.
The monitor executes one thread at a time. Assuming you have T1-T10 threads, 9 are BLOCKED and one is RUNNABLE. Every once in a while, the monitor picks a new thread to run. When that happens, the chosen/current thread, say T1, goes from RUNNABLE to BLOCKED. Then another thread, say, T2, goes from BLOCKED to RUNNABLE, becoming the current thread.
When one of the threads needs some information to be made available by another thread, you use wait(). In that case, the thread will be flagged as WAITING until it is notify()ed. So, a thread that is waiting will not be executed by the monitor until then. An example would be, wait until there are boxes to be unloaded. The guy loading boxes will notify me when that happens.
In other words, both BLOCKED and WAITING are status of inactive threads, but a WAITING thread cannot be RUNNABLE without going to BLOCKED first. WAITING threads "don't want" to become active, whereas BLOCKED threads "want" to, but can't, because it isn't their turn.
I think.
Where did you see it say stuff like that?
In the same page you linked, thread.state, it clearly states that
WAITING will be after Object.wait()
BLOCKED will be before entering synchronized
Waiting is when it's not doing anything at all. Blocked is when it's trying to start running again but hasn't been allowed to yet.
There is some confusing terminology going on here.
When a thread calls wait on an object it goes into the WAIT state.
When threads are waiting to grab a lock, they belong to the wait set for that lock, but they are in the BLOCKED state.
Confusing but somehow it makes sense!
Just as a reminder, you should always call wait() inside a while loop waiting on the condition for entering the synchronized region/critical section. This is because Java has "spurious wakeups" (essentially, a thread can wakeup at any moment for no reason).