Program gets halted: wait() and notify() - java

I am trying to achieve this: Created two different threads, one prints odd numbers, one prints even numbers. Once one thread prints a number, it has to wait for the other thread and so on, that is one-after-other.
To achieve this, i am using synchronized block along with wait() and notify().
I am creating a class whose's object will be used to pass to synchronized block in both the threads.
Here is the code:
--> This is used object which will be passed to synchronized block.
package com.vipin.multithread.variousdemos;
public class SyncObject {
public SyncObject () {
}
}
Odd Thread:
package com.vipin.multithread.variousdemos;
public class OddThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int odd_nums[] = {1,3,5,7,9};
public OddThread(SyncObject so) {
t = new Thread(this,"Odd Thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while (true) {
synchronized(so) {
System.out.println("Odd num is --->" + odd_nums[index]);
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
so.notify();
if(index>=5) {
return;
}
}
}
}
}
Even Thread: UPDATE
package com.vipin.multithread.variousdemos;
public class EvenThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int even_nums[] = {2,4,6,8,10};
public EvenThread(SyncObject so) {
t = new Thread(this, "Even thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while(true) {
synchronized(so) {
System.out.println("Even num is --->" + even_nums[index]);
so.notify(); <-- Here we are notifying.
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
//so.notify(); <-- commented out.
if(index>=5) {
break;
}
}
}
}
}
Main Application:
package com.vipin.multithread.variousdemos;
public class EvenOddDemo {
public static void main(String[] args) throws InterruptedException {
SyncObject so = new SyncObject();
OddThread ot = new OddThread(so);
EvenThread et = new EvenThread(so);
System.out.println("\nIn main thread");
Thread.sleep(1000000000);
System.out.println("Exiting main thread...");
}
}
---> As seen in the code, I am creating two threads to print even and odd numbers. I am using synchronized block, and passing object of type ==> SyncObject.
SyncObject I am passing as argument to these different threads in main.
However, this programs halts, i.e stuck only first statement gets executed, and then it waits forever:
Here is the output:
Odd num is --->1
In main thread
Even num is --->2
I am not able to understand why this program waits for ever, I am using SAME object on which we are invoking synchronized(), wait() and notify(). As per my understanding, it should work, not sure why this is not working.
Any clues as to why this is waiting forever.
UPDATE:
I did some changes in the code, UPDATE and it works fine.
I still have some doubt. Does notify() be called by the thread even if it has not locked the monitor, like in my case after i updated the code.
Sequence of events:
Odd thread gets executed first, then it calls wait() <-- it releases the monitor and now in sleep mode.
Even thread runs, prints msg, and calls notify() <-- here i am not having clear understanding.
When Even thread calls notify(), at that point it has the monitor, so when it calls notify(), does is still own the monitor?
Now, after Even thread calls notify(), then Odd thread gets notified, and hence it starts execution from the point it was sleeping. It is doing some execution and calls notify(), at that points I presume Odd thread is NOT owning the monitor, it calls notify(). So, my question is, does notify() work same whether or not the thread owns the monitor?
It is only when one do the code, one really understands this. I read book and i felt i understood everything, and seems i am back to square one!

The problem here is simply that both threads go straight into wait. Thread 1 gets so, prints value then waits. Thread 2 then gets so, prints value then waits. So both are sleeping away, since nobody is there to notify them. So, a simple fix would be to do so.notify(), right before so.wait(). Then they're not infinitely waiting.
EDIT
Odd thread starts, executes & then waits. Then even thread starts, executes, notifies & then waits. Even thread holds the lock over the monitor until it goes into wait.
When the even thread called on notify, the odd thread awakens & polls for the lock. Once the even thread goes into wait (& releases the lock), then the odd thread can obtain the lock.
If the even thread had not called on notify, then the odd thread would continue to sleep. The even thread would have gone to wait & released the lock. No thread is polling or attempting to obtain the lock, hence the program remains in the suspended state.
The documentation also provides a similar explanation. I hope that clears your doubts.

Related

Calling Java notify() within an if condition

I have just written a simple java example to get familiar with the concept of wait and notify methods.
The idea is that when calling notify(), the main thread will print the sum.
MyThread class
public class MyThread extends Thread {
public int times = 0;
#Override
public void run() {
synchronized (this) {
try {
for (int i = 0; i < 10; i++) {
times += 1;
Thread.sleep(500);
if (i == 5) {
this.notify();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Main Class
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
synchronized (t) {
t.start();
try {
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(t.times);
}
}
}
Expected Results
5 but I got 10 instead.
Well, what I though is that when notify() is called, the main thread will wakeup and execute the System.out.println(t.times) which should give 5. Then the run() will continue till it finishes the for loop which will update the value of times to 10.
Any help is highly appreciated.
Synchronized blocks imply mutual exclusion. At any given moment, only one thread is allowed to hold the lock and execute the code within a synchronized block. This rule spreads over all the blocks guarded by the same lock.
In your case, there're two such blocks that use the same lock, so it's either the main thread or the MyThread that is allowed to execute code in either of these blocks, the other thread must wait. So, you have the following scenario here:
The main thread acquires the lock.
The main thread starts the second thread.
The second thread hits the synchronized block but cannot enter it since the lock is being hold by the main thread.
The main thread calls wait(). This call releases the lock and puts the main thread into the WAITING state.
The second thread now can acquire the lock and enter the synchronized block.
The second thread counts to five and calls notify(). This call doesn't release the lock, it just notifies the main thread that it can progress as soon as it can reacquire the lock.
The main thread awakes but it cannot make progress because it cannot reacquire the lock (it's still being hold by the second thread). Remember, no two threads can be active within a synchronized block guarded by the same lock at once, and now, the second thread is still active, so the main one must continue waiting.
The second thread continues counting, sets times to 10 and eventually leaves the synchronized block, releasing the lock.
The main thread reacquires the lock and can now make progress to the println. But by this time, the times is already 10.
Using join() won't help you either because the result will be the same – the main thread can only make progress when the second one is finished.
If you want your main thread to continue execution as soon as the second thread hits 5, you need to acquire the lock and release it immediately after that event:
public class MyThread extends Thread {
public volatile int times = 0;
#Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
times += 1;
Thread.sleep(500);
if (i == 5) {
synchronized(this) {
this.notify();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Don't forget to make times volatile, otherwise JVM won't guarantee that you'll see its actual value in your main thread.
And you should also understand that this approach doesn't guarantee that your main thread prints 5. It might occur that by the time it reaches the println call, the second thread makes one or two or even more iterations and you'll see something greater than 5 (though it's highly unluckily due to the sleep() call on every iteration).

Java Thread wait and notify methods

I'm learning for OCJP and now I'm at "Thread" chapter, I have some questions about wait and notify methods. I think I understand what's happening here but I just want to make sure that I'm on the right way.I wrote this code as an example:
package threads;
public class Main {
static Object lock = new Object();
public static void main(String[] args) {
new Main().new FirstThread().start();
new Main().new SecondThread().start();
}
class FirstThread extends Thread {
public void run() {
synchronized (lock) {
lock.notify();
System.out.println("I've entered in FirstThread");
}
}
}
class SecondThread extends Thread {
public void run() {
synchronized (lock) {
try {
lock.wait();
System.out.println("I'm in the second thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
In this example the console output is I've entered in FirstThread, because the first thread starts, the notify() method is called, then the second thread starts, the wait() method is called and the String "I'm in the second thread" is not printed.
The next scenario is that I reverse the positions of new Main().new FirstThread().start(); and new Main().new SecondThread().start(); the output is
I've entered in FirstThread
I'm in the second thread
because the second thread starts, the wait() method is called, then the first thread starts, the method notify() is called, the console prints I've entered in FirstThread, the wait is released and I'm in the second thread is printed in the console.
Is that happening because the computer is so fast and the threads run sequentially? Theoretically the second start() method can be called first in my opinion is it?.
And the last question I have, is why the lock Object must be static, because if I remove the static modifier the output is always I've entered in FirstThread?
I know that static fields are loaded in JVM when the class is loaded, but I can't understand the logic of lock Object.
The threads are started sequentially, and in theory thread 1 would execute before thread 2, although it's not guaranteed (pretty sure it'll be consistent in this simple case though, as there are no real or simulated aleatory delays).
This is why when thread 2 is started slightly before, it has a chance to wait on a lock that gets notified (by thread 1) subsequently, instead of waiting forever for a lock that's already been notified once (hence, no printing).
On the static lock Object: you're binding your [First/Second]Thread nested classes to instances of Main, so the lock has to be common to both if you want them to synchronize on the same lock.
If it was an instance object, your threads would access and synchronize on a different lock, as your new Main()... idiom would get two instances of Main and subsequently two instances of lock.
"Is that happening because the computer is so fast and the threads run
sequentially? Theoretically the second start() method can be called
first in my opinion is it?. "
Yes, you can introduce a sleep() with random time, for better (unit-) test, or demonstration purpose. (Of course, the final running code should not have that sleep)
And the last question I have, is why the lock Object must be static
Principally, it does not matter whether the lock is static or not, but you have to have the possibility to access it, and it must be the same lock object. (Not one object instance for each class). In your case it must be static, otherwise it would be two different objects instances.
This is wrong because it doesn't change any shared state that the other thread can test:
synchronized (lock) {
lock.notify();
System.out.println("I've entered in FirstThread");
}
And this is wrong because it does not test anything:
synchronized (lock) {
lock.wait();
System.out.println("I'm in the second thread");
}
The problem is, lock.notify() does not do anything at all if there is no thread sleeping in lock.wait(). In your program, it is possible for the FirstThread to call notify() before the SecondThread calls wait(). The wait() call will never return in that case because the notify() call will do nothing in that case.
There's a reason why they make you enter a mutex (i.e., a synchronized block) before you can call wait() or notify(). It's because you are supposed to use the mutex to protect the shared shared state for which the waiter is waiting.
"shared state" can be as simple as a single boolean:
boolean firstThreadRan = false;
The notifier (a.k.a., "producer") does this:
synchronized(lock) {
firstThreadRan = true;
lock.notify();
...
}
The waiter (a.k.a., "consumer") does this:
synchronized(lock) {
while (! firstThreadRan) {
lock.wait();
}
...
}
The while loop is not strictly necessary in this case, but it becomes very important when more than one consumer is competing for the same event. It's good practice to always use a loop.
See https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html for a tutorial that explains wait() and notify() in more detail.

Java: two WAITING + one BLOCKED threads, notify() leads to a livelock, notifyAll() doesn't, why?

I was trying to implement something similar to Java's bounded BlockingQueue interface using Java synchronization "primitives" (synchronized, wait(), notify()) when I stumbled upon some behavior I don't understand.
I create a queue capable of storing 1 element, create two threads that wait to fetch a value from the queue, start them, then try to put two values into the queue in a synchronized block in the main thread. Most of the time it works, but sometimes the two threads waiting for a value start seemingly waking up each other and not letting the main thread enter the synchronized block.
Here's my (simplified) code:
import java.util.LinkedList;
import java.util.Queue;
public class LivelockDemo {
private static final int MANY_RUNS = 10000;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < MANY_RUNS; i++) { // to increase the probability
final MyBoundedBlockingQueue ctr = new MyBoundedBlockingQueue(1);
Thread t1 = createObserver(ctr, i + ":1");
Thread t2 = createObserver(ctr, i + ":2");
t1.start();
t2.start();
System.out.println(i + ":0 ready to enter synchronized block");
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
t1.join();
t2.join();
System.out.println();
}
}
public static class MyBoundedBlockingQueue {
private Queue<Object> lst = new LinkedList<Object>();;
private int limit;
private MyBoundedBlockingQueue(int limit) {
this.limit = limit;
}
public synchronized void addWhenHasSpace(Object obj) throws InterruptedException {
boolean printed = false;
while (lst.size() >= limit) {
printed = __heartbeat(':', printed);
notify();
wait();
}
lst.offer(obj);
notify();
}
// waits until something has been set and then returns it
public synchronized Object getWhenNotEmpty() throws InterruptedException {
boolean printed = false;
while (lst.isEmpty()) {
printed = __heartbeat('.', printed); // show progress
notify();
wait();
}
Object result = lst.poll();
notify();
return result;
}
// just to show progress of waiting threads in a reasonable manner
private static boolean __heartbeat(char c, boolean printed) {
long now = System.currentTimeMillis();
if (now % 1000 == 0) {
System.out.print(c);
printed = true;
} else if (printed) {
System.out.println();
printed = false;
}
return printed;
}
}
private static Thread createObserver(final MyBoundedBlockingQueue ctr,
final String name) {
return new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println(name + ": saw " + ctr.getWhenNotEmpty());
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
}, name);
}
}
Here's what I see when it "blocks":
(skipped a lot)
85:0 ready to enter synchronized block
85:0 entered synchronized block
85:2: saw hello
85:1: saw world
86:0 ready to enter synchronized block
86:0 entered synchronized block
86:2: saw hello
86:1: saw world
87:0 ready to enter synchronized block
............................................
..........................................................................
..................................................................................
(goes "forever")
However, if I change the notify() calls inside the while(...) loops of addWhenHasSpace and getWhenNotEmpty methods to notifyAll(), it "always" passes.
My question is this: why does the behavior vary between notify() and notifyAll() methods in this case, and also why is the behavior of notify() the way it is?
I would expect both methods to behave in the same way in this case (two threads WAITING, one BLOCKED), because:
it seems to me that in this case notifyAll() would only wake up the other thread, same as notify();
it looks like the choice of the method which wakes up a thread affects how the thread that is woken up (and becomes RUNNABLE I guess) and the main thread (that has been BLOCKED) later compete for the lock — not something I would expect from the javadoc as well as searching the internet on the topic.
Or maybe I'm doing something wrong altogether?
Without looking too deeply into your code, I can see that you are using a single condition variable to implement a queue with one producer and more than one consumer. That's a recipe for trouble: If there's only one condition variable, then when a consumer calls notify(), there's no way of knowing whether it will wake the producer or wake the other consumer.
There are two ways out of that trap: The simplest is to always use notifyAll().
The other way is to stop using synchronized, wait(), and notify(), and instead use the facilities in java.util.concurrent.locks.
A single ReentrantLock object can give you two (or more) condition variables. Use one exclusively for the producer to notify the consumers, and use the other exclusively for the consumers to notify the producer.
Note: The names change when you switch to using ReentrantLocks: o.wait() becomes c.await(), and o.notify() becomes c.signal().
There appears to be some kind of fairness/barging going on using intrinsic locking - probably due to some optimization. I am guessing, that the native code checks to see if the current thread has notified the monitor it is about to wait on and allows it to win.
Replace the synchronized with ReentrantLock and it should work as you expect it. The different here is how the ReentrantLock handles waiters of a lock it has notified on.
Update:
Interesting find here. What you are seeing is a race between the main thread entering
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
while the other two thread enter their respective synchronized regions. If the main thread does not get into its sync region before at least one of the two, you will experience this live-lock output you are describing.
What appears to be happening is that if both the two consumer threads hit the sync block first they will ping-pong with each other for notify and wait. It may be the case the JVM gives threads that are waiting priority to the monitor while threads are blocked.

notify() before exiting the synch'd block?

Is there any use in notify() as the last statement in a sync'd block ?
Eg.: Suppose the following code is running in some thread r,
synchronized(t) {
t.start();
// do stuff using t
t.notify();
}
what would i loose if I remove the line?
t.notify();
Thread r is releasing the lock of t already, and this lock is available to those waiting on it.
The code samples I worked on "behaved" the same with and without the t.notify() call up there.
The only use i can think of is, being somewhat "proactive" in notifying that the monitor of t is being released and those waiting on it will get into BLOCKED state, waiting to acquire it.
However, in this case that notify() is the last statement in the synch'd block, JVM will already know, by exiting the synch'd block, that this lock is released.
This rather is a Q on understanding some specifics on notify() & notifyAll().
TIA.
Please note: I've seen Java notify() run before wait()? and Does the position of the notify() call matter?(Java). This is a different Q than those.
//================================
EDIT: the sample code:
public class T3 {
public static void main(String[] args){
Sum t = new Sum();
synchronized(t) {
t.start();
try {
t.wait();
} catch (InterruptedException ex) {
}
}
System.out.println("Sums up to: " + t.sum);
} // main
}
class Sum extends Thread {
int sum;
public void run() {
synchronized(this) {
for(int i = 1; i <= 55 ; sum += i++);
// notify();
}
}
}
same thing when run() of class Sum is as follows:
public void synchronized run() {
for(int i = 1; i <= 55; sum += i++);
// notify();
}
If you are locking on a thread, and the thread terminates, it sends a notifyAll to whatever threads are waiting on it. See the API documentation for Thread.join:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
In your example the notification is the last thing done before the thread finishes executing, so the explicit notification is redundant.
(Note that the API documentation quoted here and Jon Skeet are both recommending you don't lock on a thread object.)
Yes. It allows other threads that are wait()ing on t to run again, instead of waiting for a notify that never comes.

threads reagarding notification

I was going through threads and I read that ..The notify() method is used to send a signal to one and only one of the threads that are waiting in that same object's waiting pool.
The method notifyAll() works in the same way as notify(), only it sends the signal to all of the threads waiting on the object.
Now my query is that if Lets say I have 5 threads waiting and through Notify() , i want to send to notification to thread 3 only, what logic should be there that notification is sent to thread 3 only ..!!
You can't directly do this with wait and notify. You'd have to set a flag somewhere, have the code in the thread check it and go back to waiting if it's the wrong thread, and then call notifyAll.
Note that if you have to deal with this, it might be a sign that you should restructure your code. If you need to be able to notify each individual thread, you should probably make each of them wait on a different object.
wait-notify is rather a low level mechanism to indicate to other threads that an event (being expected occured). Example of this is producer/consumer mechanism.
It is not a mechanism for threads to communicate to each other.
If you need something like that you are looking in the wrong way.
The following code starts up five threads and sets the third one a flag which tells it that it is the only to continue. Then all of the threads that are waiting on the same lock object lock are notified (woken-up), but only the one selected continues. Be careful, writing multi-threaded applications is not easy at all (proper synchronization, handling the spurious wake-ups, etc.) You should not need to wake up only one particular thread from the group as this points to an incorrect problem decomposition. Anyway, here you go...
package test;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.start(5);
}
private void start(int n) {
MyThread[] threads = new MyThread[n];
for (int i = 0; i < n; i++) {
threads[i] = new MyThread();
/* set the threads as daemon ones, so that JVM could exit while they are still running */
threads[i].setDaemon(true);
threads[i].start();
}
/* wait for the threads to start */
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
/* tell only the third thread that it is able to continue */
threads[2].setCanContinue(true);
/* wake up all threads waiting on the 'lock', but only one of them is instructed to continue */
synchronized (lock) {
lock.notifyAll();
}
/* wait some time before exiting, thread two should be able to finish correctly, the others will be discarded with the end of the JVM */
for (int i = 0; i < n; i++) {
try {
threads[i].join(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("Done!");
}
/** synchronization object, i.e. a lock which makes sure that only one thread can get into "Critical Section" */
private final Object lock = new Object();
/** A simple thread to demonstrate the issue */
private final class MyThread extends Thread {
private volatile boolean canContinue;
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + " going to wait...");
synchronized (lock) {
while (!canContinue) {
try {
lock.wait(1000); /* one second */
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
System.out.println(Thread.currentThread().getName() + " woken up!");
}
public void setCanContinue(boolean canContinue) {
this.canContinue = canContinue;
}
};
}
The output of the code is:
Thread-0 going to wait...
Thread-2 going to wait...
Thread-3 going to wait...
Thread-1 going to wait...
Thread-4 going to wait...
Thread-2 woken up!
Done!
So you can clearly see that only the third thread (indexed from zero) is woken up. You have to study the Java synchronization and multi-threading in more detail to understand every particular line of the code (for example, here).
I would like to help you more, but I would have to write almost a book about Java threads and that is why I just pointed out to this Java Tutorial on threads. You are right, this problematics is not easy at all, especially for beginners. So I advise you to read through the referenced tutorial and then you should be able to understand most of the code above. There is no easy way around or at least I do not know of any.

Categories