aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Thread question 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 "Thread question" Watch "Thread question" New topic
Author

Thread question

Matheus Souza
Ranch Hand

Joined: Mar 06, 2012
Posts: 38

Morning guys, I was doing another ExamLab mock and this question appeared:


It says that the answer is: Ready to print, Now printed. The explanation says that the wait() is wainting for an Trd instance, and the notifyAll() use a Thread instance. I didn't get it. Can anyone explain to me what happened?

Thanks
Norbert Muench
Greenhorn

Joined: Mar 09, 2012
Posts: 19
Looking at the code, I would say this will throw an IllegalMonitorStateException in line 14, because the wait call is not in a synchronized block.
Also, the wait is on the Trd object whereas the notifyAll is on the Thread object. So, the notifyAll will not notify the waiting thread.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4392
    
    8

Norbert Muench wrote:Looking at the code, I would say this will throw an IllegalMonitorStateException in line 14, because the wait call is not in a synchronized block.

It's in a synchronized method - that's the same thing as a block synchronized on that object.

But your second point is the important one. The wait() call in doMore() is on the Trd object. The notifyAll() call is on the Thread object. So there's no interaction going on. The Trd object is waiting for a notification that never comes.
Norbert Muench
Greenhorn

Joined: Mar 09, 2012
Posts: 19
Ah stupid me, I overlooked that the method itself was synchronized. Thanks for pointing that out.

But one other question:
As far as I can see, there's no guarantee that the output is "Ready to print, Now Printing, ". It could also be "Now Printing, Ready to Print, ", correct?
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4392
    
    8

That was my impression, yes (because the sleep periods are the same). In practice you might always get the same behaviour, but I don't think it's guaranteed.
Anayonkar Shivalkar
Bartender

Joined: Dec 08, 2010
Posts: 1506
    
    5

Norbert Muench wrote:As far as I can see, there's no guarantee that the output is "Ready to print, Now Printing, ". It could also be "Now Printing, Ready to Print, ", correct?

Correct. Theoretically, its not guaranteed in which order those Strings will be printed.


Regards,
Anayonkar Shivalkar (SCJP, SCWCD, OCMJD, OCEEJBD)
Janki Shah
Ranch Hand

Joined: Nov 23, 2011
Posts: 136
So, If we want to call notifyAll() correctly, how do we call notifyAll() on Trd object?
Norbert Muench
Greenhorn

Joined: Mar 09, 2012
Posts: 19
Same as you would call any other method.
The thread code still might get stuck in the call to wait() though, as there is no guarantee that the notifyAll() wouldn't be excuted before the wait().

Matheus Souza
Ranch Hand

Joined: Mar 06, 2012
Posts: 38

Norbert Muench wrote:Same as you would call any other method.
The thread code still might get stuck in the call to wait() though, as there is no guarantee that the notifyAll() wouldn't be excuted before the wait().



I got it. Thanks for the explanation =D
Janki Shah
Ranch Hand

Joined: Nov 23, 2011
Posts: 136
Thank you Norbert for your explanation. So, in order to work with wait(), notify(), and notifyAll()... All these three methods have to acquire a lock on an object not on threads, Right? And wait() and notify() or notifyAll() they both have to get lock on the same object to work with each other? Please correct me if I am wrong.
But this conflicts with this " the thread must own the lock on the object that wait() is being invoked on " From K & B book chapter 9 question 7.
I am very confused in this logic who should own the lock on whom??? Can you please explain this?
Norbert Muench wrote:Same as you would call any other method.
The thread code still might get stuck in the call to wait() though, as there is no guarantee that the notifyAll() wouldn't be excuted before the wait().

Norbert Muench
Greenhorn

Joined: Mar 09, 2012
Posts: 19
Janki Shah wrote:Thank you Norbert for your explanation. So, in order to work with wait(), notify(), and notifyAll()... All these three methods have to acquire a lock on an object not on threads, Right? And wait() and notify() or notifyAll() they both have to get lock on the same object to work with each other? Please correct me if I am wrong.

That is correct.

Janki Shah wrote:But this conflicts with this " the thread must own the lock on the object that wait() is being invoked on " From K & B book chapter 9 question 7.
I am very confused in this logic who should own the lock on whom??? Can you please explain this?

Locks are on objects, but they are aquired and owned by threads. When a thread enters a synchronized block, it aquires the lock on the object the synchronized block refers to. In case of a synchronized method, this will be the object the method is called for.
Once one thread has aquired a lock on an object, no other thread can aquire a lock on the same object until the thread holding the lock releases it.
Janki Shah
Ranch Hand

Joined: Nov 23, 2011
Posts: 136
Thank you Norbert. It helps a lot. Thanks once again.
Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451


By the way, will the following scenario be possible ?
1. t.start(), but the Trd's run method is not executed yet.
2. the main thread sleeps for 1 second
3. the main thread acquires the lock of t.
4. the main thread prints "Now printing"
5. the main thread notify all. But since the Trd's run method is not executed yet, the t thread is not waiting. There is no waiting thread to be notified at this moment.
6. Trd's run method begins to execute
7. t sleeps for 1 second as line 5 is execute.
8 t prints "Ready to print"
9. doMore is execute, but the thread t acquires the lock of its Trd instance and wait for it and release the lock. Will the thread t wait forever here and won't execute line 15?


The key points are step 5 and step 9. In step 5, there is no waiting thread and t notifies nothing.
In step 9, t is waiting for Trd and won't get notify.

I remember in KB's book, if the notify or notifyAll is called before the wait happens, there will be no thread to notify.
That is why wait and notify must be put inside some conditional statements.

Correct me if I am wrong.
Matheus Souza
Ranch Hand

Joined: Mar 06, 2012
Posts: 38

I have another question: when I use the syncronized keyword in a static member it means that all my template (static member - variables and methods) are lockeds?
Norbert Muench
Greenhorn

Joined: Mar 09, 2012
Posts: 19
Matheus Souza wrote:I have another question: when I use the syncronized keyword in a static member it means that all my template (static member - variables and methods) are lockeds?

No, it means that threads executing the synchronized method need to aquire a lock on the class object.
is functionally equivalent to


Helen Ma wrote:By the way, will the following scenario be possible ?

I would say yes. And the solution is described in K&B chapter 9, section "Using wait() in a Loop". Basically, before calling wait() you should check if the event you want to wait for has already happened.
Matheus Souza
Ranch Hand

Joined: Mar 06, 2012
Posts: 38

Norbert Muench wrote:
Matheus Souza wrote:I have another question: when I use the syncronized keyword in a static member it means that all my template (static member - variables and methods) are lockeds?

No, it means that threads executing the synchronized method need to aquire a lock on the class object.


So if I create new instace of MyClass, the synchronized methods would be locked already?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18570
    
    8

Matheus Souza wrote:So if I create new instace of MyClass, the synchronized methods would be locked already?


I'm not sure quite what this means, but let me answer one of the questions it might mean:

No, creating an object will not automatically cause any code to acquire any locks it didn't already have.

If it meant something else, please correct my guess.
Matheus Souza
Ranch Hand

Joined: Mar 06, 2012
Posts: 38

Paul Clapham wrote:
Matheus Souza wrote:So if I create new instace of MyClass, the synchronized methods would be locked already?


I'm not sure quite what this means, but let me answer one of the questions it might mean:

No, creating an object will not automatically cause any code to acquire any locks it didn't already have.

If it meant something else, please correct my guess.


This is not what meant. I want to know if I lock an method syncronized, the whole set of static members would be locked too?
Norbert Muench
Greenhorn

Joined: Mar 09, 2012
Posts: 19
Matheus Souza wrote:This is not what meant. I want to know if I lock an method syncronized, the whole set of static members would be locked too?

I think you misunderstand how locking works. If one thread holds a lock to an object, it doesn't prevent other threads from modifying any of the objects member variables. It just prevents other threads from aquiring a lock to the same object. And threads will only aquire a lock when starting a synchronized block or synchronized method.

Take the following code as an example:


Now imagine you have two threads, thread 1 and thread 2. Thread 1 has just called MyClass.staticSyn1() and is in the middle of working through that method. So it holds a lock to the MyClass class object.
If thread 2 would start running now, it could modify the static member MyClass.si1. The fact that thread 1 holds the lock on the MyClass class object doesn't come into play here at all. Thread 2 could also call MyClass.static1(), because that class method isn't synchronized.
But what happens, if thread 2 tries to call MyClass.staticSyn1(), MyClass.staticSyn2() or syn1() on any object of type MyClass?
At the start of the synchronized block, the thread would try to aquire a lock on MyClass.class. That lock is already held by thread 1 however. So in this case thread 2 would be moved from the running state to the blocked state. Once thread 1 releases the lock on MyClass.class, thread 2 would aquire the locks and would be moved from blocked to runnable (and eventually to running).
Matheus Souza
Ranch Hand

Joined: Mar 06, 2012
Posts: 38

Norbert Muench wrote:
Matheus Souza wrote:This is not what meant. I want to know if I lock an method syncronized, the whole set of static members would be locked too?

I think you misunderstand how locking works. If one thread holds a lock to an object, it doesn't prevent other threads from modifying any of the objects member variables. It just prevents other threads from aquiring a lock to the same object. And threads will only aquire a lock when starting a synchronized block or synchronized method.

Take the following code as an example:


Now imagine you have two threads, thread 1 and thread 2. Thread 1 has just called MyClass.staticSyn1() and is in the middle of working through that method. So it holds a lock to the MyClass class object.
If thread 2 would start running now, it could modify the static member MyClass.si1. The fact that thread 1 holds the lock on the MyClass class object doesn't come into play here at all. Thread 2 could also call MyClass.static1(), because that class method isn't synchronized.
But what happens, if thread 2 tries to call MyClass.staticSyn1(), MyClass.staticSyn2() or syn1() on any object of type MyClass?
At the start of the synchronized block, the thread would try to aquire a lock on MyClass.class. That lock is already held by thread 1 however. So in this case thread 2 would be moved from the running state to the blocked state. Once thread 1 releases the lock on MyClass.class, thread 2 would aquire the locks and would be moved from blocked to runnable (and eventually to running).


I think that I got it. Thanks for the effort on the explanation =D
 
jQuery in Action, 2nd edition
 
subject: Thread question