aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes notifyall Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "notifyall" Watch "notifyall" New topic
Author

notifyall

cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
I've another question about notifyall.
Here's the code extracted from Dan's mock exam:
Result:
Some or all of the numbers 0 through 9 could be printed. There is no guarantee that anything will be printed.

Explanation:
All of the threads started in method B.m1 are daemon threads so the program can run to completion even if some or all of the daemon threads have not run.

That's OK.
But if I delete t1.setDeamon(true) in the above code, I would expect that the program will not exit unless all of the threads have run. And that all the threads waiting in the instance b waiting pool will run one after the other.
When I run this program on my computer by command-line, I have instead the following result:
O and a waiting cursor but no more...
Why haven't I relatively quickly 0123456789?
Thanks in advance for your help,
Cyril.


SCJP 1.4, SCWCD, SCBCD, IBM XML, IBM Websphere 285, IBM Websphere 287
Alton Hernandez
Ranch Hand

Joined: May 30, 2003
Posts: 443
Originally posted by cyril vidal:

But if I delete t1.setDeamon(true) in the above code, I would expect that the program will not exit unless all of the threads have run. And that all the threads waiting in the instance b waiting pool will run one after the other.
When I run this program on my computer by command-line, I have instead the following result:
O and a waiting cursor but no more...
Why haven't I relatively quickly 0123456789?
Thanks in advance for your help,
Cyril.

notifyall() will notify all the waiting threads - those that managed to enter the monitor and isssued the wait. But there might still be some threads who are yet to enter the monitor( or the synchronized method in A). These threads have yet to issue the wait() method.
Eventually, the notifyall() will wakeup all the threads in the wait state and exit. But for those thread that have yet to issue the wait(), when they do so, then they will be waiting forever because noone else is issuing the notify signal.
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
Alton,
first thanks for your response.
notifyall() will notify all the waiting threads - those that managed to enter the monitor and isssued the wait

1�)I thought just one and only one thread would manage to enter a specified monitor at the same time.
Did you mean by this that when the notifyall is executed, depending on thread scheduler' s behavior, all the threads (from 0 to 9) are not in the waiting pool? Because although start method has been invoked for the nine, the scheduler may have invoked before it executes the nine run methods So, there may be one or two or five threads in the waiting pool ... We don't know.. Is it correct?
2�) When notifyall is executed, then one of the threads waiting in the pool for instance b acquires the lock, and continues executing.
In my case, it's the first one, so I have 0 printed in the console.
3�) But after this, there's no other notify or notifyall() invocation, thus nothing more happens, and I have 8 waiting threads in the wainting pool, waiting for ever...
4�) I don't understand exactly the diffrence between notifyall and notify.
For me, as far as I understand for now, notifyall notify all the threads waiting for the lock for an objet. But if all are notified, just one will acquire the lock.
So, what's the difference with notify that notify only one Thread?
In both cases, just one Thread will acquire the lock and will be able to run, no?
I think I completely miss something here, but i don't grasp what exactly.
Thanks for your help,
Cyril.
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
When a thread calls wait, it is added to the wait set of an object. When another thread calls notify on an object, some thread is removed from the wait set of the object. When a thread calls notifyAll on an object, all threads are moved from the wait set of the object.
Thread-5 calls wait()

Thread-1 calls notifyAll()

Thread-1 is preempted, but Thread-1 still has the lock on the object, Thread-2 is selected to run

Or maybe, Thread-1 releases the lock and then blocks, and Thread-4 is selected to run

Maybe threads that need to acquire locks are on a different queue from the ready queue.
[ July 22, 2003: Message edited by: Marlene Miller ]
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
Hi Marlene,
Thanks for your response.
I'm sorry, but it is difficult for me to get a good understanding of this lock's mechanism.

does it mean that Thread2 and Thread3 don't need lock, since they already have it?
So, many threads may have the lock on a determined object at the same time???
Here, Thread1 because it is running, Thread2 and Thread3.
The more time spends, the less I get about threads...
COuld you please tell me where I'm wrong?
Thanks in advance,
Cyril.
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
OK, I think I've just understood...
Of course, only one thread may keep the lock on a object. Here in the example, Thread 2 and Thread3 don't need the lock because they don't enter an synchronized block, that's all...
Maybe threads that need to acquire locks are on a different queue from the ready queue.

In my book Complete Java Certification Study guide, it's told about Seeking Lock state, when a thread has gone out of Waiting state and has not yet obtained the lock.
When lock is obtained, then it enters the Ready state.
So, in your schema, perhaps one step (Seeking lock) is missing...Correct me if I'm wrong...
Cyril.
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
To answer the question, notifyAll() has for effect to move all the waiting threads of the wait set of an object to the Seeking Lock state for that object, whereas notify will juste move one of these threads to the Seeking Lock state: the choice of Threads depends on the environment...
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
Hi Cyril
In method m1() ten threads are being created. All these ten threads are being set as daemons. All threads have been started i.e. each thread's run may execute. I said may because it is possible that exactly after calling t1.start() the thread's run method doesn't executes and the main thread comes out of the for loop and executes the next line: synchronized (this) {notifyAll();}. When this happens the main thread will be about to exit and as all other threads are daemons it won't wait for them.
As for your output after deleting t1.setDaemon().
Now the program may wait because as I said before there is a chance that the main thread completes before the other thread's run method is executed now when the run method hasn't executed (or even if it did execute the program didn't reach this line: synchronized (obj) {obj.wait();} ) then the thread will not be having a lock on the object. So it means it is currently not waiting. After this the main thread may exit and the other threads may also go into the waiting state. Now when the main thread exits there is no code which invokes notify on these threads so you may have a/few waiting threads.
Try checking this by giving the newly created threads a very high and then by giving a very low priority. When you give high priority then there may not be a single thread waiting and in case of low priority all threads may be waiting.
So the two coding for m1() are :

Probably the output will be 0123456789
and for the second code just change this line to t1.setPriority(1); and then probably there will be no output and the application will keep waiting.
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Thread-2 and Thread-3 don't need the lock because they don't enter an synchronized block

Yes. Thread-2 and Thread-3 are just some arbitrary threads that are not currently selected to run. They are not trying to execute synchronized methods on the object that threads 1, 4, 5 are using. Maybe Thread-2 is the garbage collector thread.
So, in your schema, perhaps one step (Seeking lock) is missing.

Yes, my diagram is missing a step. Somehow the virtual machine has to know that some threads need to acquire a lock before they can execute. Those threads must compete for the lock.
notifyAll() has for effect to move all the waiting threads of the wait set of an object to the Seeking Lock state for that object, whereas notify will juste move one of these threads to the Seeking Lock state: the choice of Threads depends on the environment

Yes.
[ July 22, 2003: Message edited by: Marlene Miller ]
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
Thanks Anupam for your explanations! I think i've graped it now.

Try checking this by giving the newly created threads a very high and then by giving a very low priority. When you give high priority then there may not be a single thread waiting and in case of low priority all threads may be waiting.
So the two coding for m1() are :

code:
--------------------------------------------------------------------------------
private void m1(){for (int i = 0; i < 10; i++){A t1 = new A(this);t1.setName(String.valueOf(i));//t1.setDaemon(true); t1.setPriority(10); //this linet1.start();}synchronized (this) {notifyAll();}}
--------------------------------------------------------------------------------
Probably the output will be 0123456789
and for the second code just change this line to t1.setPriority(1); and then probably there will be no output and the application will keep waiting.


In fact, all the difference seems holding between
and

In the first case, zero, one or sometimes two thread(s) is able to run before the notifyall call, whereas in the second case, all have time to run before this call. Output: 0123456789.

2�) I was completely wrong in my first comprehension:
2�) When notifyall is executed, then one of the threads waiting in the pool for instance b acquires the lock, and continues executing.
In my case, it's the first one, so I have 0 printed in the console.

As said above, when notifyall is executed, all the threads being in the waiting pool move out from this state and enter in concurrence for lock.
As main thread is about to exit, then, two cases:
1�) the other threads started are not demon threads, and when they will execute their run method, they will wait for ever (because no more notify or notifyall invocation from main thread)
2�) the other threads started are demon threads, and although the waiting state, main method completes.
So, both cases will give same output in screen (that is the same numbers), but in first case, a waiting cursor will appear and not in the second case...
Alton Hernandez
Ranch Hand

Joined: May 30, 2003
Posts: 443
Hi Cyril,

Did you mean by this that when the notifyall is executed, depending on thread scheduler' s behavior, all the threads (from 0 to 9) are not in the waiting pool?

Yes, that is what I meant. It is possible that only 1 or 2 threads will manage to enter the synchronized method and issued the wait() call before the main method issued the notifyall(). As for the remaining threads, they will eventually enter the synchronized method and go into the wait state. However, they will not wake up because no more notify signal is coming.
Note that even though the remaining threads have not entered the synchronized method, that doesn't mean that they have not started yet. They may not be able to enter because they could not get hold of the lock.
So if you see an output of
01 and then a waiting cursor
then one possible scenario is:

1. Threads 0 to 9 started
2. Thread-0 obtains the lock, issue wait, goes into a wait state, and releases the lock
3. Thread-1 obtains the lock, issue wait, goes into a wait state, and releases the lock
4. Thread-main obtains the lock, issue notifyall, exit, and releases the lock.
5. Thread-0 and Thread-1 wakes up
6. Thread-0 obtains the lock, completes the method (prints 0), and releases the lock.
7. One after the other Threads 2 to 9 obtain the lock, issue wait, go into the wait-state, and release the lock.
8. Thread 1 obtains the lock, completes the method(prints 1), and releases the lock.

So what you have now are 8 threads in the wait state waiting forever.
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
Very good explanations
Thanks Alton!!
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
Hi Alton

1. Threads 0 to 9 started
2. Thread-0 obtains the lock, issue wait, goes into a wait state, and releases the lock
3. Thread-1 obtains the lock, issue wait, goes into a wait state, and releases the lock
4. Thread-main obtains the lock, issue notifyall, exit, and releases the lock.
5. Thread-0 and Thread-1 wakes up
6. Thread-0 obtains the lock, completes the method (prints 0), and releases the lock.
7. One after the other Threads 2 to 9 obtain the lock, issue wait, go into the wait-state, and release the lock.
8. Thread 1 obtains the lock, completes the method(prints 1), and releases the lock.

Why would Thread-0 and Thread-1 again obtain the lock and then print. Once out of the wait state they do not need to again accquire a lock.
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
Hi Anupam,

Why would Thread-0 and Thread-1 again obtain the lock and then print. Once out of the wait state they do not need to again accquire a lock.

When a thread issue the waiting state after notify/notifyall call, it doesn't automatically has the lock. It enters the seeking lock state and enter in concurrence with all other threads that need the lock on the same object.
Cyril.
Alton Hernandez
Ranch Hand

Joined: May 30, 2003
Posts: 443
Originally posted by Anupam Sinha:
Hi Alton
Why would Thread-0 and Thread-1 again obtain the lock and then print. Once out of the wait state they do not need to again accquire a lock.

Hi Anupam,
At step 6, in this scenario, Thread-0 is successful in obtaining the lock against all other threads. It has to obtain the lock in order to continue on.
Same explanation for Thread-1.
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
Hi Andres
I mean that step 6 should be written as
Thread-0 obtains the lock, releases the lock and completes the method (prints 0). Same for Thread-1.
This because the method itself is not synchronized only a few statements are. So once the statements on which the lock has to be kept have been executed the lock can be released. Or am I missing something.
One more thing that might be relevant to this topic is this thread. Before reading the before mentioned thread I was under the impression that once notify has been called and the code is something like

it will not need to reacquire the lock since there is no code left to be executed that needs a lock.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: notifyall