What causes a synchronization lock to get stuck? - java

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.

Related

Synchronized statement doesn't work the second time

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.

Java Threading: Unexpected behavior when providing timeout argument in lock.wait()

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

Interrupting a blocking method before the method call

I'm reading this book, (O'Reillys Java Threads 3rd ed., which for now has very bad explanations), and I have encountered this code:
//in RandomCharacterGenerator class
public void run( ) {
while (!isInterrupted()) {
nextCharacter( );
try {
Thread.sleep(getPauseTime( ));
} catch (InterruptedException ie) {
return;
}
}
}
And the following explanation (producer is the instance of upper class in the main thread):
producer.interrupt( );
If the main thread executes this statement while the RandomCharacterGenerator thread is sleeping, the RandomCharacterGenerator thread gets the interrupted exception and immediately returns from the run() method. Otherwise, when the character-feeding thread next gets to the top of its loop, it sees that the interrupted flag has been set and returns from its run() method then. Either way, the random character generator thread completes its task.
Note that this technique does not completely eliminate the possibility that we sleep for some amount of time after the thread is asked to stop. It's possible for the main thread to call the interrupt() method just after the RandomCharacterGenerator has called the isInterrupted() method. The character-reading thread still executes the sleep() method, which won't be interrupted (since the main thread has already completed the interrupt() method). This is another example of a race condition that we solve in the next chapter. Since the race condition in this case is benign (it just means we sleep one more time than we'd like), this is sufficient for our purposes.
Second paragraph is completely unclear to me. My first question is: How can we sleep one more cycle? If we interrupt the thread when sleeping it goes out of run, if we interrupt before sleep it will interrupt sleep as soon as it starts sleeping (I tested that, and I think that's true? Am I right), if we interrupt after sleep it will brake the loop.
Second question: In this example (this is the whole code from the book) is the check in loop completely unnecessary, and can it stand while (true) with the same outcome, so that first paragraph about the top of the loop is complete nonsense?
The book is wrong. Interrupting the thread before it sleeps will make the sleep() method throw an InterruptedException immediately.
Quote from Java Concurrency in Practice:
A good way to think about interruption is that it does not actually interrupt a running thread; it just requests that the thread interrupt itself at the next convenient opportunity. (These opportunities are called cancellation points.) Some methods, such as wait, sleep, and join, take such requests seriously, throwing an exception when they receive an interrupt request or encounter an already set interrupt status upon entry.
(emphasis mine)
In this particular example, using while(true) would lead to the same effect. But in other cases, if the loop never calls an interruptible method, or if you want to exit as soon as possible, you'll have to regularly check if the thread is interrupted to be able to detect the interruption.
The book believes you will spend an extra cycle in the following case:
RandomCharacterGenerator -> isInterrupted = false;
Main -> interrupt()
RandomCharacterGenerator -> runs through code
RandomCharacterGenerator -> sleeps
RandomCharacterGenerator -> isInterrupted = true
It actually will interrupt on the sleep, but the thing it is trying to get at that is important is that you may run through the code one more time after calling interrupt()

Java: How can I notify a thread only if it is waiting?

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.

Using wait() without notify() when in synchronized code piece (java)

I wanted to know if it's possible to use wait() on a synchronized piece of code without using notify(), something like this:
wait_on(B):
synchronized(B.monitor) {
B.count--
while (B.count > 0) { /* wait */ }
}
Thanks in advance
You need notify or notifyAll to awaken the thread from its wait state. In your sample the code would enter the wait and stay there (unless interrupted).
Know the difference between wait, yield, and sleep. Wait needs to be called in a synchronized block, once the wait is entered the lock is released, and the thread stays in that state until notify is called. Yield returns the thread to the ready pool and lets the scheduler decide when to run it again. Sleep means the thread goes dormant for a fixed period of time (and from there it goes to the ready pool).
Make sure you call wait on the same object that you’re synchronizing on (here it’s B.monitor).
No! Only option is to wait with a timeout, which surely will not help you.
If you change the /* wait */ into a call to wait(), and no one will call notify() or notifyAll(), then this thread will never wake up...
If it is a barrier that you want, you will need to notifyAll your other threads:
wait_on(B) {
synchronized(B.monitor) {
B.count--
while (B.count > 0) {
B.monitor.wait()
}
B.monitor.notifyAll();
}
}
Regards,
Pierre-Luc

Categories