In a first Java thread I have:
while (!isDone) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
doSomeVeryLongRunningTask();
}
In another thread, I want to send a notify signal:
synchronized (thr1) {
thr1.notify();
}
However, if the doSomeVeryLongRunningTask() method is running, I don't want the second thread to get blocked. I only want to notify the first thread if it is waiting so that the second thread can continue it tasks without getting locked.
How might I fix the code above to accomplish this?
They problem you want to fix does not exist. synchronized blocks will block the thread only if another thread is already inside a synchronized block synchronizing on the same object. Since your doSomeVeryLongRunningTask() will be called outside the synchronized block the notifying thread will never get blocked if the other thread is inside the doSomeVeryLongRunningTask() method.
But this raises another problem. You seem to be thinking, that wait and notify invocations are always paired. This is not the case, you may call notify as often as you wish without anyone listening to it. It might be also the case that a wait invocation returns “spuriously”, i.e. for no apparent reason. You therefore need to define another “hard condition” which is defined by a state that is modified and checked inside the synchronized block.
E.g. inside the class whose instance you have in your thr1 variable, you can define a boolean flag:
boolean condition;
Then you modify you waiting method like this:
while(!isDone) {
try {
synchronized(this) {
while(!condition) wait();
if(isDone) break;// skip doSomeVeryLongRunningTask()
condition=false;
}
} catch(InterruptedException e) {
e.printStackTrace();
}
doSomeVeryLongRunningTask();
}
And the notifying code to:
synchronized(thr1) {
thr1.condition=true;
thr1.notify();
}
This way your notifying code still won’t get blocked (at least never for a significant time) but the waiting thread will wait for at least one notification to happen within one loop cycle.
It seems what is blocking your program is not the notify() (it doesn't block ever) but the two synchronized blocks that are synchronizing on the same object.
I don't think there is a workaround to what you ask. Check this link to know why: http://javarevisited.blogspot.com/2011/05/wait-notify-and-notifyall-in-java.html
The notify() call doesn't block. Only wait() blocks. You can call notify even if there isn't another thread waiting, but then make sure your algorithm is correct. If you expect to notify only once, then another thread arriving after the notify will wait() forever.
The advised pattern is to use notifyAll() AND to have ALL waiting threads check their wake-up condition each time they are notified AND before starting the first Wait.
The synchronized in modern Java is about as fast as --i, because this is about what is internally happening thanks to hardware compareAndSet mechanisms. The only moment this slows down noticeably, is when more than one thread is arriving at the synchronized block and therefore at least one has to wait.
Related
I have this simple code, it's simply a testing case
try
{
synchronized(this) {
while(number != 4)
{
System.out.println("Waiting...");
this.wait();
}
number = 4;
this.notifyAll();
}
}
catch(InterruptedException e)
{}
Of what I know regarding use of the wait() method, once wait is invoked, what comes after should be done. However I can't see to get the wait to end in this case. I have attempted to place a second synchronized block but that doesn't seem to work.
Do you know what could be causing the wait to hang? I looked up deadlocking but that seems to be an entirely different matter.
Think u better get some idea from here
then modify your code accordingly, as long there is no another thread is running.
The wait() method causes the current thread to wait indefinitely until another thread >either invokes notify() for this object or notifyAll().
Do you know what could be causing the wait to hang?
You have a loop that's waiting for number to be set to 4. No code is executed that sets number to 4. Therefore the loop waits forever.
while(number != 4)
{
System.out.println("Waiting...");
this.wait();
}
/* you can't get here until some other thread sets number to 4. */
number = 4;
this.notifyAll();
}
The wait call does not terminate until some other code calls notify, and then when you wake up out of the wait, you'll loop back again unless number is now 4.
You can't have a thread simultaneously be in wait and executing the code that issues the notify. And if wait didn't wait, it would not be useful.
Not intending to be rude, but the problem here seems to be a lack of understanding of sequential execution of program code.
I am curious whether it is possible to pause a thread t in Java and allow another thread to resume it later, by having t run the following pause code:
while(true) {
try {
synchronized(t) {
t.wait();
}
} catch(InterruptedException e) {
break;
}
}
And then resuming the thread t by calling .interrupt() on it. However, I have read about spurious wake-ups, and so I wondered whether my code can fail, in the sense of exiting the while-loop despite no other thread calling .interrupt() on it. While this answer and this answer state that there are no spurious interrupts, and hence my code will never fail, the Java docs does not seem to address this. My question probably boils down to whether InterruptedException is ever thrown without the thread being interrupted by .interrupt(). Is there any official source or documentation that confirms this?
Summary
So, although technically this works, there are numerous reasons why this should not be done. Oracle's documentation states that interruption should only be utilized for cancellations. But if you were to do this, it will clear the interrupt status and the previously waiting thread will receive an InterruptedException.
Alternative
Lets step through a brief, simplified example.
Object obj = new Object;
synchronized (obj) {
while(condition) {
obj.wait();
}
}
A thread here will obtain the monitor.
The thread will begin to wait via wait(), and release the monitor. Always utilize wait() inside a conditional because threads are subject to get spurious wake-ups from wait(). At this point, you have achieved forcing a thread to wait.
Lets investigate how we go about returning the thread to work.
synchronized(obj) {
obj.notify();
}
The notify() will wake up the first waiting thread on the monitor. Now, if you want all waiting threads to wake up, utilize notifyAll() instead. This is the intended purpose and functionality of wait()/notify() and thus should be utilized over wait()/interrupt(). For an additional example, see this article.
UPDATE:
Turns out there wasn't anything wrong with my Synchronized statements. I made a mistake earlier on in the code and it was blocking there. I apologize for the wasted time and thank you for all the help.
PS. The CountDownLatch suggested by #sh0rug0ru was better suited to my needs and was exactly what I needed.
PREVIOUS:
This is the relevant part of the code:
synchronized (readyLock) { //sets this thread's status to ready
readyLock.notify();
System.out.println("notify works");
try {
readyLock.wait();
System.out.println("woke up from sleep");
} catch (InterruptedException ex) {
Logger.getLogger(Battleship_server_clientThread.class.getName()).log(Level.SEVERE, null, ex);
}
readyLock.notify();
}
while (true) { //game loop
//Some stuff here
synchronized (readyLock) { //sets this thread's status to ready
readyLock.notify();
System.out.println("notify works");
try {
readyLock.wait();
System.out.println("woke up from sleep");
} catch (InterruptedException ex) {
Logger.getLogger(Battleship_server_clientThread.class.getName()).log(Level.SEVERE, null, ex);
}
readyLock.notify();
}
//Some more stuff here
}
The readyLock object is initialized in another class as a static final variable:
static final Object readyLock = new Object();
The Synchronized statement works the first time, as in the first synchronized block of statements. But the synchronized block inside the while loop doesn't work. It's the exact same code in both the places.
This class is a thread that is run twice from a server. It's for a two player game. The rest of the code is here.
I'm trying to figure out why the second synchronized statement doesn't work. I think it's just blocking there for some reason.
NOTE All the System.out.println(""); lines are for debugging.
When you use notify(), this would come with a state change.
When you wait() you should check for that state change.
Otherwise you risk either;
the notify is lost if nothing is waiting at that moment.
wait can wake spuriously.
This is covered in the documentation for those methods.
Don't use notify, use notifyAll. notify will pick a random waiting thread. If that thread goes back to wait state and notify isn't called again, all the other waiting threads will stay waiting, and you have yourself a deadlock.
Using notifyAll will give all threads in wait state a chance to proceed.
notify is very dangerous, and there is almost no good reason to use it.
Better yet, why are you using wait/notify/notifyAll in the first place? What are you trying to achieve? Whatever concurrency pattern you are trying to implement probably already has an implementation in java.util.concurrent which will more clearly and more safely do whatever it is you are trying to do.
As I said in comments, the second notify() in each synchronized block is suspicious. If the purpose for wait()ing is to make the two threads you describe take turns, so that only one runs at any given time, then your code is broken. Here's what then actually happens:
One thread enters the (one of the) synchronized blocks, excluding all others.
That thread notifies one other blocked waiting on readyLock, if there is any, so that it can proceed when the current thread releases that monitor.
The current thread blocks, releasing the monitor and await a notification of its own.
The other thread does its thing, until it comes to the same or a similar block, at which time it notifies the waiting thread and thereafter itself begins waiting.
The original thread proceeds, immediately notifying the waiting thread.
The original thread exits the synchronized block, releasing the readyLock's monitor
The second thread can then return from wait(), running concurrently with the first.
In itself, that does not explain a deadlock, but if you don't expect the two threads to be running concurrently then there's any number of ways trouble could ensue.
Here's how you might structure that scenario better:
synchronized (readyLock) {
setMyTurn(false);
otherPlayer.setMyTurn(true);
readyLock.notify();
while (!isMyTurn()) {
try {
readyLock.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Battleship_server_clientThread.class.getName()).log(
Level.SEVERE, null, ex);
}
}
}
Note that you might want to consider notifyAll() instead of notify(). The distinction doesn't matter if there can be only one other thread waiting on the monitor, but it is otherwise safer if all potential waiters utilize a loop and condition check as shown.
Say i've got the following code:
public void run(){
while (true){
function1();
...
functionN();
}
}
And i wanna exit 'gracefully' - Which means for me that once i sent a shutdown signal and currently the thread is at functionK(), The thread will 'break' the loop and exit run.
So i've tried using Thread.interrupt() like this:
public void run(){
while (true){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
But this doesn't work - The thread continutes to run endlessly even with interrupt flag on.
Just for the record:
public void run(){
while (!thread.isInterrupted()){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
Stops the loop, But doesn't help me. Since each function does something that might take several minutes and there are a lot of different function so checking before each function whether interrupted flag is one might be costly (Especially since most of the times the application runs smoothly).
I wonder whether there is a special mechanism i can use for that kind of problem.
The API documentation is very clear about this:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
So you can only rely on this exception if you're waiting for object monitors. There are a couple of other exceptions thrown by certain I/O operations but if you don't use them either, there is no other option than to check the interrupted() flag.
What you can do though is to re-organise your code: if you've got N methods that are called one after the other, is it not possible to abstract them out into a loop? More often than not it is possible to find a way to refactor code to support interruption, the exact way depends on your actual scenario. My first question would be: why does a single method run for minutes? That sounds a bit fishy (though it may be justified).
Either way, interruptibility isn't something that comes for free, you have to actively design interruption points if you want your code to be more responsive to interruption than the length of the main loop.
One more thing though: checking the interrupted() flag is most definitely NOT costly. Not when you spend minutes in your main loop, and it's a lot cheaper than constructing and handling an exception. I'd go as far as to say that you'll find very few things faster than a call to Thread.isInterrupted().
Actually if you are doing CPU bound work in your methods, you have to check for Thread.interrupted() by yourself and throw InterruptedException yourself. Java won't magically do it for you, unless you park at some specifically designed spaces, such as Semaphore.wait() etc.
Your second example will keep looping after the interrupt. This is because InterruptedException doesn't actually mean that the Thread's interrupted flag is set; in fact, you don't need to check it at all.
To fix this, you can simply re-interrupt the thread (to allow callers to know that the thread was interrupted), and then break:
public void run(){
while (true) {
try {
function1();
//...
functionN();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
}
As stated in the book "Java concurrency in Practice" :"Java does not provide any mechanism for safely forcing a thread to stop what is doing", so you must implement something on your side. checking the interrupted flag and handling the InterruptedException is the best way to manage thread cancellation.
If one of you function1()...functionN() is in the middle of a database transaction or a HTTP call is up to your program to handle the cancellation; you can wait until to n seconds and save the current state or cancel the transaction and roolback, the action to perform is dictated by your application logic.
Unfortunately I'm not going to be able to give full context to this, since there's too much complexity in the surrounding code. The short of it is this:
I have a block of code that's waiting on a lock:
synchronized (lock) {
lock.wait();
}
Which works as expected. Fairly straightforward -- it acquires the lock, releases it when it starts waiting, another thread acquires the lock and then notifies on it.
However, as soon as I provide a timeout, the behavior changes entirely.
synchronized (lock) {
lock.wait(60000L);
}
Again, should be fairly straightforward (and this works as expected in several other places in the code). However, in this one case, execution basically halts until the timeout occurs. My only guess as to what seems to be happening is it's not releasing the lock when it enters the wait -- the notifier is never able to acquire the lock, so the wait sleeps until it times out. And even worse, it's a blocking sleep -- no other threads are able to wait on the lock and it forces the execution to be entirely synchronous.
Anyone have any ideas as to what might be happening here? It's a fairly simple function and there's nothing weird going on with nested synchronization blocks at any point. Considering that by providing no timeout it should wait indefinitely, if the notifier itself was broken the code would be hanging forever, but that's not the case. It only stops working once the timeout is provided.
Any thoughts would be greatly appreciated.
OS: OS X 10.8.5
JDK: 1.6.0, 1.7.0.45 and 1.7.0.67
Your example does not show a while() loop around the wait() call. That suggests that you may not completely understand the use case for wait and notify. Here's one example:
// This object is used to synchronize *EVERY* method
// that can change the value of count.
final Object lock = new Object();
int count;
void waiter() {
synchronized(lock) {
while(count <= 0) {
lock.wait();
}
//do something that you are only allowed to do
//when count > 0.
}
}
void notifier() {
synchronized(lock) {
count++;
if (count >= 0) {
lock.notify();
}
}
}
[Edit: Added this paragraph, thank's Nathan Hughes for reminding me that...] The wait() call is in a loop because the wait()ing thread still has to re-acquire the lock after the lock has been notified: if thread A is waiting for the condition to become true, and thread B makes the condition true and calls notify(); there's no guarantee that thread C won't get the lock first, and make the condition false again before the wait() call is able to return.
Also, wait() is allowed to return even when the object has not been notified (that's called a "spurious wakeup").
The condition-to-be-waited-for is explicit in the code (i.e., count > 0).
Nothing changes the condition-to-be-waited-for except when synchronized on the same lock object that is used for wait() and notify() calls.
Irrespective of whether you provide a timeout or not the wait method on an object releases the lock held on the object by the current thread as commented by John.
With the code that you have given and based on your description of scenario my guess is that the moment lock.wait(60000L) is executed JVM releases the lock on the object meanwhile any other thread which is in runnable/running state might be picked up and if they are synchronizing on the same object then they might take the lock before your notifier thread would take the lock.
This behaviour is difficult to debug as it depends on JVM profiler to pick which thread should be run. So as you explained just when your lock.wait(60000L) is executed it need not always be that the notifier thread alone should pick up the lock on the common object . If there is any other thread which is also waiting on the common object it can very well get the lock finally leading to notifier thread not being able to get the lock and hence the lock.wait(60000L) gets timedout.
Whenever you use lock.wait(..) you have to use the lock.notify() or lock.notifyAll(). Make sure you use that where it makes sense in your logic and it will 'wake up' the lock before the timeout (considering the timeout value you put is enough). Here it's some guide for its usage, i hope its useful: http://www.javamex.com/tutorials/wait_notify_how_to.shtml