Java synchronization wait and notify methods - java

I'm a newbie to synchronization and trying to understand how wait and notify works.
Question:-
The programs executes 2 threads - T1 & T2 simultaneously but based on the output T1 runs first, executes the question(first) method, prints the question, sets the flag(true), runs the notify() method, executes the question(second) method & enters the wait method. Now T2 starts and executes.
Why does T2 doesn't start until T1 calls the wait method of the Object Chat.
When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). so, which thread listens to this notify method.
My codes:
package TestThread;
class Chat {
boolean flag = false;
public synchronized void Question(String msg) {
System.out.println("Question method = " + flag);
if (flag) {
try {
System.out.println("Question method wait start");
wait();
System.out.println("Question method wait finish");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = true;
notify();
}
public synchronized void Answer(String msg) {
System.out.println("Answer method = " + flag);
if (!flag) {
try {
System.out.println("Answer method wait start");
wait();
System.out.println("Answer method wait finish");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = false;
notify();
}
}
class T1 implements Runnable {
Chat m;
String[] s1 = { "Hi", "How are you ?", "I am also doing fine!" };
public T1(Chat m1) {
this.m = m1;
new Thread(this, "Question").start();
}
public void run() {
for (int i = 0; i < s1.length; i++) {
m.Question(s1[i]);
}
}
}
class T2 implements Runnable {
Chat m;
String[] s2 = { "Hi", "I am good, what about you?", "Great!" };
public T2(Chat m2) {
this.m = m2;
new Thread(this, "Answer").start();
}
public void run() {
for (int i = 0; i < s2.length; i++) {
m.Answer(s2[i]);
}
}
}
public class MultiThread {
public static void main(String[] args) {
Chat m = new Chat();
new T1(m);
new T2(m);
}
}
Result:-
Question method = false
Hi
Question method = true
Question method wait start
Answer method = true
Hi
Answer method = false
Answer method wait start
Question method wait finish
How are you ?
Question method = true
Question method wait start
Answer method wait finish
I am good, what about you?
Answer method = false
Answer method wait start
Question method wait finish
I am also doing fine!
Answer method wait finish
Great!

Why does T2 doesn't start until T1 calls the wait method of the Object
Chat.
You have a same object 'm' and passed it to different threads and there is method level synchronization , so the moment a 'call' enters the question() there will be lock on whole object till wait() is called Hence answer method will be blocked.
When the question method is executed first time and notify() method is
called, there is no wait() on the chat object(since t2 did not yet
start). so, which thread listens to this notify method.
notify() has no significance for the first time, synchronized method has to finish thats all. as said earlier answer() is not executed till the question() finishes / releases the lock (calling wait())

Why does T2 doesn't start until T1 calls the wait method of the Object Chat?
You've got a race condition. Either of the two threads will execute first. Since they both share a single Chat instance, whose methods are synchronized, one will block until the other has unlocked the monitor on the Chat instance.
When the question method is executed first time and notify() method is
called, there is no wait() on the chat object(since t2 did not yet
start). so, which thread listens to this notify method?
None do.

1.) Why does T2 doesn't start until T1 calls the wait method of the Object Chat?
Actually T2 starts before that but you don't notice because you don't have any logging statements to show up. Put a System.out inside run method of T2 and run your program a few times. You will see T2 starting before T1 calls wait method. Keep in mind T2 cannot enter the Chat object's Answer method since its lock is acquired by T1 before wait() is eventually called.
Another thing to keep in mind is that there is no guarantee of the order in which threads will be started. Just because T1.start appears before T2.start , does not mean T1 will always be started first. Thread scheduler makes that decision.
2.)When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). so, which thread listens to this notify method.
--If there has been no wait calls , then notify won't impact any threads.

Related

Need to clear my mind on methods wait() e notify();

class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet)
try {
wait();
} catch (Exception e) {
}
;
System.out.println("Pego : " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet)
try {
wait();
} catch (Exception e) {
}
;
this.n = n;
valueSet = true;
System.out.println("Inserido : " + n);
notify();
}
}
class Producer2 implements Runnable {
Q q;
Producer2(Q q) {
this.q = q;
new Thread(this, "Geradora").start();
}
public void run() {
int i = 0;
while (true) {
q.put(i++);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer2 implements Runnable {
Q q;
Consumer2(Q q) {
this.q = q;
new Thread(this, "Consumidora").start();
}
public void run() {
while (true) {
q.get();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class PCFixed {
public static void main(String[] args) {
Q q = new Q();
new Producer2(q);
new Consumer2(q);
}
}
Text from the book:
Inside get(), wait() is called. This suspends the execution till Producer notify...
My question is, Once I instantiate Producer and Consumer, the execution reaches put, not get. So how come it calls get first and then call wait() inside get()?
The system can only be in one of two states:
It is empty
valueSet is false, the put method will not even once enter that while loop and thus never invokes wait(), and the get method would wait().
It is full
valueSet is true, the get method will not even once enter that while loop and thus never invokes wait(), and the put method would wait().
Explanation
Because the get and put methods are synchronized, only one can be running (and note that wait() will open the gates and let other code run. It'll re-acquire the lock before wait() actually exits - for code to go on past a wait(), both notify() must be called, and whatever called it needs to get to the end of it synchronized block/method.
The code starts off in 'empty' mode.
It doesn't matter if you attempt to invoke put and get simultaneously; these methods are synchronized on the this reference so only one can actually run, the other would freeze until the lock is available. Thus, we have two options:
The put call wins. In this case, the put call will immediately set the value and not wait at all, sets the mode to 'full' (valueSet = true), does a useless notify() that has no effect but also does no harm, and ends. The get call was waiting to start and can now start. It will not wait at all (as it is in "full" mode; valueSet == true), gets the value and prints it, sets the mode back to empty, does another useless notify, and exits.
The get call wins. In this case, the get call will enter the while loop and waits. This releases the lock, which means the put call can now go. It will not wait at all (as the while loop's condition is false, which means it runs zero times), it sets a value, and notify() - that 'releases' the get() call which now merely waits for the lock to be available to continue. The put method ends, thus releasing the lock. The get call continues and fetches the value. It then does a useless notify, and exits as well.
Instead you attempt to run 2 put calls simultaneously. One wins and immediately sets as usual, then the other runs and will immediately enter wait mode and will be stuck there (as will any further put calls, they all run into the wait() call and wait there), until you call get() in some thread, this will get a value, set the thing to be in 'empty' mode, and notifies one arbitrary thread, thus unlocking it. It will put its value and set your object back to "full" mode and exit, leaving the other putters still waiting around. Another get call would immediately proceed, fetch it, notify another one of the waiting put calls, and so on.
Because both Producer2 and Consumer2 create a new thread in their constructors.
So calling
new Producer2(q);
In the main method, doesn't stop the execution, it goes immediately to the next line which is
new Consumer2(q);
Which is where the call to q.get happens

Can a java thread waiting with wait() ,notify itself?

I came across the following e example to implement custom suspend and wait from some website.
// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for (int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
...................
I am more concerned about the ob1.mysuspend() and ob1.myresume() calls. When my suspend is called then ob1 will be placed into the blocking queue associated with the runnable object it is using. When ob1 calls myresume, then how does it work as ob1 is already in waiting queue for the same object, can the waiting object enters another synchronised method and then signals notify to itself?How does this work?What am I missing?
The thread is written so that while an instance of NewThread is running, another thread can call mysuspend to suspend that running thread. Again, a thread other than the suspended thread calls myresume to resume the suspended thread.
There also appears to be a data race because mysuspend writes to suspendFlag without any synchronization. That means, the thread that needs to be suspended may not see that write immediately. mysuspend must be declared synchronized, or suspendFlag must be volatile.
This code is flat out broken.
Straight up broken: JMM violation
The mysuspend method (which should be named mySuspend, by the way) updates a field that is then read from another thread, and isn't synchronized. This is an error - and a really nasty one because you cannot reliably test that it is an error. The Java Memory Model (JMM) states that any write to a field may be observable or not, at the discretion of the JVM implementation, unless a so-called Happens-Before/Happens-After relationship is established (there are many ways to do it; usually you do so via synchronized, volatile, or some other concurrency tool built on these primitives, such as the latches and queues in the java.util.concurrent package).
You do not establish such a relationship here, meaning, that suspendFlag = true results in a schroedingers cat variable: The other thread that reads this field may read true or false, the JVM gets to decide what you see. Hence: A bug, and, untestable. bad. Any field that is read/written to by multiple threads needs to be written extremely carefully.
Mark that method synchronized, that's a good first step.
Wait and Notify
You've got it flipped around: You must in fact hold the synchronized lock on x when you invoke wait on x (here, x is this).
To call x.wait() (you are calling this.wait(), effectively), you must first be in a synchronized(x) block. Once the wait 'goes through', the code releases the lock (other synchronized(x) blocks can run). To invoke x.notify() you must also hold that lock.
wait does not return until the lock is re-established.
In other words:
public void foo() {
wait();
}
will fail at runtime. Try it. Guaranteed exception. In the mean time, this:
public void foo() {
synchronized (this) {
// code before wait
wait();
// code after wait
}
}
is executed as if it is written like this:
public void foo() {
synchronized (this) {
// code before wait
release_lock(this);
this.wait();
acquire_lock(this);
// code after wait
}
}
Where acquire_lock is guaranteed to actually take a while (because by definition whatever invoked notify() to wake you up is currently holding it! So wait is always a two-hit thing: You need to be both notified AND the lock needs to be reacquired before your code will continue). Except, of course, acquire_lock and release_lock don't exist, and unlike this hypothetical code, wait() is more atomic than that.

notifyAll() not awakening processes

I'm programming a little Java program where I need to create threads (philosophers in my code), and these philosophers need to change of state between thinking, hungry and eating.
I'm not that far into the project and I have the next problem:
public class NewMain {
static Philosopher [] p;
public static void main(String[] args) {
p = new Philosopher[5];
p[0] = new Philosopher(0);
p[1] = new Philosopher(1);
p[2] = new Philosopher(2);
p[3] = new Philosopher(3);
p[4] = new Philosopher(4);
for (int i = 0; i<5; i++) {
try{
p[i].run();
if(i == 4) {
p.notifyAll();
}
}
catch(IllegalMonitorStateException e) {}
}
}
}
I'm creating 5 philosophers(threads). Each one of those has a wait() instruction in their code:
#Override
public void run() {
int rand;
if (status == 0) {
System.out.println("Philosopher " + id + " is waiting.");
try {
wait();
System.out.println("Awoken");
while(status == 0) {
System.out.println("Philosopher " + id + " is thinking.");
sleep(100);
rand = ThreadLocalRandom.current().nextInt(0,100);
if(rand > 95){
status = 1;
System.out.println("Philosopher " + id + " changed state to hungry.");
}
}
}
catch(InterruptedException e) {
System.out.println("Error!");
}
catch(IllegalMonitorStateException e) {}
}
}
The problem is that when invoking notifyAll(), the processes don't awake and they just die after executing the run() method of each thread.
If anyone is wondering, I'm not using synchronized because I need to run the methods at the same time.
Also, I've tried to put notifyAll() inside the run() method of the threads.
Can anyone tell me what's going on and why are the threads not continuing
with their code?
Problems
notify[All]() and wait() should be used on the same instance. You are notifying on the array Philosopher[] p, but waiting on this which is a Philosopher. It's like I am waiting for you, but you are notifying Sarah that you're going to be late.
You have created the threads but haven't started them properly. Calling run will execute the method in the current thread. Use the method start instead. It begins execution concurrently.
To use x.notify[All]() or x.wait(), you have to be within a synchronised block synchronized(x) { ... }. Ignoring IllegalMonitorStateException won't help you at all.
Answers
... why are the threads not continuing with their code?
They might call wait after the 4th thread notifies them.
... the processes don't awake and they just die ...
They don't die, they still wait until you terminate the program.
I'm not using synchronizedbecause I need to run the methods at the same time
You need to run the methods at the same time correctly, right? Here, synchronisation is required at least for building wait-notify communication.
p is an array of Runnable. when you write
p[i].run();
Then, you are invoking run method (actually you haven't started a thread here instead called run method) using object stored at p[i] location. Now, as per notifyAll
Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.
You should have used start() instead run() to start a new thread.
notify() and notifyAll are used when thread(s) are waiting to acquire monitor on current object.

Is it possible that 2 synchronized methods of an object are accessible by 2 threads at the same time?

This question was asked to me in an interview. Before I had told him this,
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
Consider the snippet:
Q1:
public class Q1 {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
Producer1:
public class Producer1 implements Runnable {
Q1 q;
Producer1(Q1 q) {
this.q = q;
new Thread(this, "Producer").start();
}
#Override
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
Consumer1
public class Consumer1 implements Runnable {
Q1 q;
Consumer1(Q1 q) {
this.q = q;
new Thread(this, "Consumer").start();
}
#Override
public void run() {
while (true) {
q.get();
}
}
}
PC1:
public class PC1 {
public static void main(String args[]) {
Q1 q = new Q1();
new Producer1(q);
new Consumer1(q);
System.out.println("Press Control-C to stop.");
}
}
So, he asked as soon as you have created this thread new Producer1(q), then according to you, the synchronized int get() method must have been locked by the same thread, i.e, by new Producer1(q) when it accessed synchronized int put(). I said yes.
But I checked in eclipse, get is callable by new Consumer1(q). The program works perfect.
Where am I going wrong?
O/P:
The call to wait() will release the monitor for the time waiting.
That's what is documented for Object.wait():
The current thread must own this object's monitor. The thread
releases ownership of this monitor and waits until another thread
notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the
notifyAll method. The thread then waits until it can
re-obtain ownership of the monitor and resumes execution.
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
What you forgot to add here is "except if the lock is released".
...and it is the case in your example, when calling wait.
The documentation specify :
The thread releases ownership of this monitor and waits until another
thread notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the notifyAll method.
Since the lock is released, you step in the other method (and the condition is true because the boolean was modified). Once in the other method, you release the lock again, then call notify and you wake up the old thread which terminates (re-modify boolean to pass the condition in other method, and notify). That way you step between both methods ad-infinitum.
wait() and notify() is acts as a signal between threads, to control the threads to do or to not do the stuff.
The program works perfect because here 2 threads (Producer, Consumer) which fight for the one lock (monitor). When Consumer aquires the lock (Q1 object) then Producer is waiting for the lock. When Consumer finishes his work it release the lock. Consumer releases the lock also when wait() method has been called, because wait() sets thread to Waiting state with lock release. It's time for Producer to aquire the lock and does his work. When Producer thread notify() calls then Consumer continue his work (when aquired the lock). The same is right for Producer.
Resume: Q1 object is a lock for all threads. If it aquired someone then others are blocked and the answer is - it not possible to get an access at the same time to the get(), put() methods more then 2 threads.
I think that the question is ambiguous. (E.g., what does "accessible" mean?)
IMO, a good interview question should not have a right answer and a wrong answer. A good interview question should be a conversation starter, that gives you an opportunity to show how much you know about the subject.
When I am asking the interview questions, I like a candidate who can see through the question, and get down to the underlying mechanism. E.g.,
What the JLS guarantees is that no two threads can be _synchronized_
on the same instance at the same time...
Then we could explore questions like, how could two threads enter the same synchronized method at the same time? (e.g., synchronized on different instances), how could two threads be in the same synchronized method for the same instance at the same time (one of them could be in a wait() call), ...
A thread can not access a synchronized block of code unless it has aquired a lock on the object that guards the block. In your case, the synchronized keyword uses the lock of the object in which it has been declared. So as long as a thread is executing get(), no other thread can execute the put().
If you apply this, when put() sets the value, it notifies consumer which accepts the value. The code should work even after you have removed the wait() and notify() calls from both get and put methods

Difference between notify() and notifyAll()

I know that similar questions have been discussed in this site, but I have not still got further by their aid considering a specific example. I can grasp the difference of notify() and notifyAll() regarding Thread "awakeining" in theory but I cannot perceive how they influence the functionality of program when either of them is used instead of the other. Therefore I set the following code and I would like to know what is the impact of using each one of them. I can say from the start that they give the same output (Sum is printed 3 times).
How do they differ virtually? How could someone modify the program, in order for the applying notify or notifyAll to play a crucial role to its functionality (to give different results)?
Task:
class MyWidget implements Runnable {
private List<Integer> list;
private int sum;
public MyWidget(List<Integer> l) {
list = l;
}
public synchronized int getSum() {
return sum;
}
#Override
public void run() {
synchronized (this) {
int total = 0;
for (Integer i : list)
total += i;
sum = total;
notifyAll();
}
}
}
Thread:
public class MyClient extends Thread {
MyWidget mw;
public MyClient(MyWidget wid) {
mw = wid;
}
public void run() {
synchronized (mw) {
while (mw.getSum() == 0) {
try {
mw.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Sum calculated from Thread "
+ Thread.currentThread().getId() + " : " + mw.getSum());
}
}
public static void main(String[] args) {
Integer[] array = { 4, 6, 3, 8, 6 };
List<Integer> integers = Arrays.asList(array);
MyWidget wid = new MyWidget(integers);
Thread widThread = new Thread(wid);
Thread t1 = new MyClient(wid);
Thread t2 = new MyClient(wid);
Thread t3 = new MyClient(wid);
widThread.start();
t1.start();
t2.start();
t3.start();
}
}
UPDATE:
I write it explicitly. The result is the same whether one uses notify or notifyAll:
Sum calculated from Thread 12 : 27
Sum calculated from Thread 11 : 27
Sum calculated from Thread 10 : 27
Therefore my question: What is the difference?
The difference is subtler than your example aims to provoke. In the words of Josh Bloch (Effective Java 2nd Ed, Item 69):
... there may be cause to use notifyAll in place of notify. Just as placing the wait invocation in a loop protects against accidental or malicious notifications on a publicly accessible object, using notifyAll in place of notify protects against accidental or malicious waits by an unrelated thread. Such waits could otherwise “swallow” a critical notification, leaving its intended recipient waiting indefinitely.
So the idea is that you must consider other pieces of code entering wait on the same monitor you are waiting on, and those other threads swallowing the notification without reacting in the designed way.
Other pitfalls apply as well, which can result in thread starvation, such as that several threads may wait for different conditions, but notify always happens to wake the same thread, and the one whose condition is not satisfied.
Even though not immediately related to your question, I feel it is important to quote this conclusion as well (emphasis by original author):
In summary, using wait and notify directly is like programming in “concurrency assembly language,” as compared to the higher-level language provided by java.util.concurrent. There is seldom, if ever, a reason to use wait and notify in new code. If you maintain code that uses wait and notify, make sure that it always invokes wait from within a while loop using the standard idiom. The notifyAll method should generally be used in preference to notify. If notify is used, great care must be taken to ensure liveness.
This is made clear in all sorts of docs. The difference is that notify() selects (randomly) one thread, waiting for a given lock, and starts it. notifyAll() instead, restarts all threads waiting for the lock.
Best practice suggests that threads always wait in a loop, exited only when the condition on which they are waiting is satisfied. If all threads do that, then you can always use notifyAll(), guaranteeing that every thread whose wait condition has been satisfied, is restarted.
Edited to add hopefully enlightening code:
This program:
import java.util.concurrent.CountDownLatch;
public class NotifyExample {
static final int N_THREADS = 10;
static final char[] lock = new char[0];
static final CountDownLatch latch = new CountDownLatch(N_THREADS);
public static void main(String[] args) {
for (int i = 0; i < N_THREADS; i++) {
final int id = i;
new Thread() {
#Override public void run() {
synchronized (lock) {
System.out.println("waiting: " + id);
latch.countDown();
try { lock.wait(); }
catch (InterruptedException e) {
System.out.println("interrupted: " + id);
}
System.out.println("awake: " + id);
}
}
}.start();
}
try { latch.await(); }
catch (InterruptedException e) {
System.out.println("latch interrupted");
}
synchronized (lock) { lock.notify(); }
}
}
produced this output, in one example run:
waiting: 0
waiting: 4
waiting: 3
waiting: 6
waiting: 2
waiting: 1
waiting: 7
waiting: 5
waiting: 8
waiting: 9
awake: 0
None of the other 9 threads will ever awaken, unless there are further calls to notify.
notify wakes (any) one thread in the wait set, notifyAll wakes all threads in the waiting set. notifyAll should be used most of the time. If you are not sure which to use, then use notifyAll.
In some cases, all waiting threads can take useful action once the wait finishes. An example would be a set of threads waiting for a certain task to finish; once the task has finished, all waiting threads can continue with their business. In such a case you would use notifyAll() to wake up all waiting threads at the same time.
Another case, for example mutually exclusive locking, only one of the waiting threads can do something useful after being notified (in this case acquire the lock). In such a case, you would rather use notify(). Properly implemented, you could use notifyAll() in this situation as well, but you would unnecessarily wake threads that can't do anything anyway.
Javadocs on notify.
Javadocs on notifyAll.
Once only one thread is waiting to sum to not be zero, there is no difference. If there are several threads waiting, notify will wake up only one of them, and all the other will wait forever.
Run this test to better understand the difference:
public class NotifyTest implements Runnable {
#Override
public void run ()
{
synchronized (NotifyTest.class)
{
System.out.println ("Waiting: " + this);
try
{
NotifyTest.class.wait ();
}
catch (InterruptedException ex)
{
return;
}
System.out.println ("Notified: " + this);
}
}
public static void main (String [] args) throws Exception
{
for (int i = 0; i < 10; i++)
new Thread (new NotifyTest ()).start ();
Thread.sleep (1000L); // Let them go into wait ()
System.out.println ("Doing notify ()");
synchronized (NotifyTest.class)
{
NotifyTest.class.notify ();
}
Thread.sleep (1000L); // Let them print their messages
System.out.println ("Doing notifyAll ()");
synchronized (NotifyTest.class)
{
NotifyTest.class.notifyAll ();
}
}
}
I found what is going on with my program. The three Threads print the result even with the notify(), because they do not manage to enter the waiting state. The calculation in the widThread is performed quickly enough to preempt the entering of the other Threads in the waiting state, since it depends on the condition mw.getSum() == 0 (while loop). The widThread calculates the sum, so that the remaining Threads do not ever "see" its value as 0.
If the while loop is removed and the start of widThread comes after the start of the other Threads, then by notify() only one Thread prints the result and the others are waiting forever, as the theory and the other answers indicate.

Categories

Resources