It was a design decision.
Java’s concurrency model needs “locks” and it was decided that each object was to be associated with a lock.
The wait and notify methods are not associated with a thread but with a lock, so the decision of coupling locks and objects meant that each object should have wait and notify methods that operate on that object’s lock.
Explanation and Example
A gas station has a single toilet, the key for which is kept at the service desk. The toilet is a shared resource for passing motorists. To use this shared resource the prospective user must acquire a key to the lock on the toilet. The user goes to the service desk and acquires the key, opens the door, locks it from the inside and uses the facilities.
Meanwhile, if a second prospective user arrives at the gas station he finds the toilet locked and therefore unavailable to him. He goes to the service desk but the key is not there because it is in the hands of the current user. When the current user finishes, he unlocks the door and returns the key to the service desk. He does not bother about waiting customers. The service desk gives thekey to the waiting customer. If more than one prospective user turns up while the toilet is locked, they must form a queue waiting for the key to the lock. Each thread has no idea who is in the toilet.
Obviously in applying this analogy to Java, a Java thread is a user and the toilet is a block of code which the thread wishes to execute. Java provides a way to lock the code for a thread which is currently executing it using the synchorinized keywokd, and making other threads that wish to use it wait until the first thread is finished. These other threads are placed in the waiting state. Java is NOT AS FAIR as the service station because there is no queue for waiting threads. Any one of the waiting threads may get the monitor next, regardless of the order they asked for it. The only guarantee is that all threads will get to use the monitored code sooner or later.
Finally the answer to your question: the lock could be the key object or the service desk. None of which is a Thread.
However, these are the objects that currently decide whether the toilet is locked or open. These are the objects that are in a position to notify that the bath room is open (“notify”) or ask people to wait when it is locked wait.
If the threads were designed to give the lock to one another, then one thread might ‘chose’ a ‘friendly’ thread leading to nepotism.
Hence, the wait and notify methods have to be in Object class.
Threads borrow keys from JVM and return to JVM.
NOW what is a lock?
Locks are inbuilt, hidden objects in a class. For static synchorinized methods the class object has a lock and for non-staic classes the objects instances themselves are the lock.
That is why while blocking a piece of code (instead of an entire method) we use synchronized(this){ …;}
If the same thread has to access various piece of code which are mutually exclusive to modifications then simply create two objects and call them lock 1 and lock 2 and use these two locks to synchornize.
example. if within the same code there are two areas that have to be synchronized and if the two areas are mutually exclusive then we SHOULD NOT USE this keyword for locking.
In our analogy, if there is a condom vending machine in the toilet, then if an user who does not want to buy condoms is using the bathroom, then the same key will lock the toilet and the vending machine and if there is a person in the queue who wants to use the toilet only to get a condom, then he is unnecessarily locked. In this case the gas station has to use two rooms and two keys. That way using one will not affect the other.
Need clarifications let me know.
Most importantly wait, notify , notifyall come into picture only when synchonizing a piece of code.











Great work Devesh !!!
Comment by vinod krish — August 18, 2008 @ 6:54 am
very good explaination
Comment by Peter Li — November 3, 2008 @ 9:03 pm
Ultimate explanation. Good work bro.
Comment by sandeep kumar — January 20, 2009 @ 8:58 am
You have posted very good note here about the Thread and Object classes and use of their methods.
Comment by B Singh — March 19, 2009 @ 12:47 pm
Very Good Explanation..
Comment by Bala — March 26, 2009 @ 6:44 am
Nice Explanation Devesh.
But can you explain upon the comment “If the threads were designed to give the lock to one another, then one thread might ‘chose’ a ‘friendly’ thread leading to nepotism.”??
Comment by Anirudha Sen — May 22, 2009 @ 2:18 pm
Wassup
I’ve been a member for the last 14 months, and I’ve been loving every post of it.
Comment by david — June 25, 2009 @ 10:41 pm
I had read “code is like good music!” and you proved that
Comment by piskodrocho — July 10, 2009 @ 7:58 pm
This look interesting,
Peace,
Comment by BlueHornet — July 18, 2009 @ 12:59 am
superb
Comment by Muthukumar — September 28, 2009 @ 6:21 am
That’s great.
Comment by Anurag Nigam — September 30, 2009 @ 2:33 pm
Nice one Devesh….This explains exactly what I was looking..
Comment by RaviL — October 21, 2009 @ 2:03 am
The most satisfactory explaination for this question I ve found so far.
But can you explain the ‘Friendly Thread’ paradigm in the statement “If the threads were designed to give the lock to one another, then one thread might ‘chose’ a ‘friendly’ thread leading to nepotism.”
Comment by Tanvi — October 23, 2009 @ 3:54 am
Very nice explanation……
Comment by Pranay — December 19, 2009 @ 6:03 am
awsome man………..thx a lot………
Comment by GogiB — February 21, 2010 @ 7:47 am
That’s great.Superb explaination my dear friend…
Comment by Mukul — February 22, 2010 @ 7:25 am
Really good explanation..
Comment by Kiran — April 16, 2010 @ 9:34 am
Great work Mr. Devesh..keep it up.
Comment by Reavaivy — May 7, 2010 @ 12:56 pm
Great notes
Comment by Meselussy — May 17, 2010 @ 2:22 am
Nice example and explanation….
Thanks to share your ideas….
Comment by Niraj — June 22, 2010 @ 8:47 am
Thanks
Comment by PesseToorkGox — July 9, 2010 @ 6:34 am
Thanks for writing this blog..
Comment by john — July 18, 2010 @ 7:42 am
Keep it up.gr8 blog for Java Guys
Comment by Thomas — July 21, 2010 @ 3:35 pm
Greak work.Really this explaination answered many of my questions in threads.
Thank u very much for ur effort.
Comment by Babu — October 20, 2010 @ 1:17 pm
I got the good explanation after 10days of search.
Thanks
Comment by Silapolxxzz — October 20, 2010 @ 2:22 pm
Nice explanation .But I have few doubts.I have written one sample producer,consumer application as below
It runs fine.But I have one doubt,Here in main method we are creating two threads Producer,Consumer in order to access same object “Q”.So when we call Producer(q),it will invoke run method of the thread class.We are calling put() method (which is in Q class) inside run method.So far fine.
Now we have put() and get() methods which are synchronized means only one thread can execute that particular block of code.Here in the put () method itself we are calling wait() method for other threads to wait.
Here my doubt is any how only one thread is coming inside the block.Then why we are mentioning other threads to wait in the same block.
Could you please clear my doubt asap and check the below code.
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
if(!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) {
if(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println(“InterruptedException caught”);
}
this.n = n;
valueSet = true;
System.out.println(“Put: ” + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, “Producer”).start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, “Consumer”).start();
}
public void run() {
while(true) {
q.get();
}
}
}
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println(“Press Control-C to stop.”);
}
}
Comment by sasi — December 23, 2010 @ 4:41 am
Hello,
Nice to be registered on javaqna.wordpress.com.
Comment by zhuzhu — January 11, 2011 @ 11:23 am
Great explanations
Comment by scatpeeD — February 2, 2011 @ 7:21 pm
Great explanation !!! Devesh
Comment by abhijit — April 8, 2011 @ 2:31 pm
Can you explain, why wait(), notify() are declared as final in the Object class?
Comment by abhijit — April 8, 2011 @ 2:35 pm
Good Explanation
Comment by Srinibas — May 13, 2011 @ 9:10 am
Great explanation!!
- Mihail
Comment by Mihail — May 25, 2011 @ 10:26 am
Great Work, Keep it up
Comment by Amit Yadav — May 26, 2011 @ 10:28 am
Hi
wait(),notify(),notifyAll() method are use to processes availability of an object.
mainly use to communicate the object.
these method are final method define in Object class.
these are available for all classes without extends the Thread class,if these are not define in java.lang.Object class so you need to extends these method according to need.
Comment by kundan ranjan — July 12, 2011 @ 6:23 pm
NIce bro……..
Comment by kranthi — November 18, 2011 @ 7:20 pm
Excellent job done! Thank u very much
Comment by Abdul Latheef — December 17, 2011 @ 5:22 am
Great work Devesh
Comment by shaan — January 24, 2012 @ 4:48 am
Great desciption !!
Comment by jotirajyr — June 5, 2012 @ 12:35 am
Nice explanation….
Comment by srini — June 14, 2012 @ 2:11 pm
nice explaination…
Comment by Dinesh Kumar Sharma — August 23, 2012 @ 7:16 am
its awesome explanation never found anywhere.:)
Comment by Anoop — October 30, 2012 @ 11:38 am
great explanation.
M impressed
Comment by GAUTAM TIWARI — December 6, 2012 @ 10:57 am