Concept behind putting wait(),notify() methods in Object class

119,895

Solution 1

I am just having hard time to understand concept behind putting wait() in object class For this questions sake consider as if wait() and notifyAll() are in thread class

In the Java language, you wait() on a particular instance of an Object – a monitor assigned to that object to be precise. If you want to send a signal to one thread that is waiting on that specific object instance then you call notify() on that object. If you want to send a signal to all threads that are waiting on that object instance, you use notifyAll() on that object.

If wait() and notify() were on the Thread instead then each thread would have to know the status of every other thread. How would thread1 know that thread2 was waiting for access to a particular resource? If thread1 needed to call thread2.notify() it would have to somehow find out that thread2 was waiting. There would need to be some mechanism for threads to register the resources or actions that they need so others could signal them when stuff was ready or available.

In Java, the object itself is the entity that is shared between threads which allows them to communicate with each other. The threads have no specific knowledge of each other and they can run asynchronously. They run and they lock, wait, and notify on the object that they want to get access to. They have no knowledge of other threads and don't need to know their status. They don't need to know that it is thread2 which is waiting for the resource – they just notify on the resource and whomever it is that is waiting (if anyone) will be notified.

In Java, we then use objects as synchronization, mutex, and communication points between threads. We synchronize on an object to get mutex access to an important code block and to synchronize memory. We wait on an object if we are waiting for some condition to change – some resource to become available. We notify on an object if we want to awaken sleeping threads.

// locks should be final objects so the object instance we are synchronizing on,
// never changes
private final Object lock = new Object();
...
// ensure that the thread has a mutex lock on some key code
synchronized (lock) {
    ...
    // i need to wait for other threads to finish with some resource
    // this releases the lock and waits on the associated monitor
    lock.wait();
    ...
    // i need to signal another thread that some state has changed and they can
    // awake and continue to run
    lock.notify();
}

There can be any number of lock objects in your program – each locking a particular resource or code segment. You might have 100 lock objects and only 4 threads. As the threads run the various parts of the program, they get exclusive access to one of the lock objects. Again, they don't have to know the running status of the other threads.

This allows you to scale up or down the number of threads running in your software as much as you want. You find that the 4 threads is blocking too much on outside resources, then you can increase the number. Pushing your battered server too hard then reduce the number of running threads. The lock objects ensure mutex and communication between the threads independent of how many threads are running.

Solution 2

For better understanding why wait() and notify() method belongs to Object class, I'll give you a real life example: Suppose 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 the key 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 synchronized keyword, 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 bathroom is open (“notify”) or ask people to wait when it is locked wait.

Solution 3

The other answers to this question all miss the key point that in Java, there is one mutex associated with every object. (I'm assuming you know what a mutex or "lock" is.) This is not the case in most programming languages which have the concept of "locks". For example, in Ruby, you have to explicitly create as many Mutex objects as you need.

I think I know why the creators of Java made this choice (although, in my opinion, it was a mistake). The reason has to do with the inclusion of the synchronized keyword. I believe that the creators of Java (naively) thought that by including synchronized methods in the language, it would become easy for people to write correct multithreaded code -- just encapsulate all your shared state in objects, declare the methods that access that state as synchronized, and you're done! But it didn't work out that way...

Anyways, since any class can have synchronized methods, there needs to be one mutex for each object, which the synchronized methods can lock and unlock.

wait and notify both rely on mutexes. Maybe you already understand why this is the case... if not I can add more explanation, but for now, let's just say that both methods need to work on a mutex. Each Java object has a mutex, so it makes sense that wait and notify can be called on any Java object. Which means that they need to be declared as methods of Object.

Another option would have been to put static methods on Thread or something, which would take any Object as an argument. That would have been much less confusing to new Java programmers. But they didn't do it that way. It's much too late to change any of these decisions; too bad!

Solution 4

In simple terms, the reasons are as follows.

  1. Object has monitors.
  2. Multiple threads can access one Object. Only one thread can hold object monitor at a time for synchronized methods/blocks.
  3. wait(), notify() and notifyAll() method being in Object class allows all the threads created on that object to communicate with other
  4. Locking ( using synchronized or Lock API) and Communication (wait() and notify()) are two different concepts.

If Thread class contains wait(), notify() and notifyAll() methods, then it will create below problems:

  1. Thread communication problem
  2. Synchronization on object won’t be possible. If each thread will have monitor, we won’t have any way of achieving synchronization
  3. Inconsistency in state of object

Refer to this article for more details.

Solution 5

Answer to your first question is As every object in java has only one lock(monitor) andwait(),notify(),notifyAll() are used for monitor sharing thats why they are part of Object class rather than Threadclass.

Share:
119,895
Sunny
Author by

Sunny

Technology Enthusiast with 8 year experience, Skilled in Java, Android, Angular, Oracle/MarkLogic Database, Requirements Analysis, Agile Methodologies, Spring Framework, and PL/SQL. Strong consulting professional with a Bachelor of Technology (B.Tech) focused in Information Technology from Kurukshetra University. Love solving problems, debugging issues, and finding out of box solutions. Have great communication and presentation skills. Well verse with MS tools for documentation

Updated on September 29, 2020

Comments

  • Sunny
    Sunny over 3 years

    I am just having hard time to understand concept behind putting wait() in Object class. For this questions sake consider if wait() and notifyAll() are in Thread class.

    class Reader extends Thread {
        Calculator c;
        public Reader(Calculator calc) {
            c = calc;
        }
    
        public void run() {
            synchronized(c) {                              //line 9
            try {
                System.out.println("Waiting for calculation...");
                c.wait();
            } catch (InterruptedException e) {}
                System.out.println("Total is: " + c.total);
            }
        }
    
        public static void main(String [] args) {
            Calculator calculator = new Calculator();
            new Reader(calculator).start();
            new Reader(calculator).start();
            new Reader(calculator).start();
            calculator.start();
        }
    }
    
    class Calculator extends Thread {
        int total;
        public void run() {
            synchronized(this) {                     //Line 31
                for(int i=0;i<100;i++) {
                    total += i;
                }
                 notifyAll();
            }
        } 
    }
    

    My Question is that what difference it could have made? In line 9 we are acquiring lock on object c and then performing wait which satisfy the condition for wait that we need to acquire lock on the object before we use wait and so is case for notifyAll we have acquired lock on object of Calculator at line 31.

  • Sunny
    Sunny over 10 years
    true, but if wait was part of Thread class then also i think they could have shared the lock
  • Gray
    Gray over 10 years
    My answer specifically talks about one monitor per object. Also, in Java you can also use ReentrantLock or other locking mechanisms built into the JDK if you so wish.
  • Alex D
    Alex D over 10 years
    OK, noted, +1 for including that point. It's true that later JRE versions include explicit lock objects, but right from day one, the implicit mutexes have been there, and that is why wait and notify were made methods on Object. If explicit lock objects, or better yet, condition queue objects were included in the original JRE, then wait and notify would certainly have been associated with them.
  • Sunny
    Sunny over 10 years
    Wow self explanatory, but as you have pointed I wish to get in detail why we call .Wait () from the synchronized block as in wait state it releases the lock for others which makes the resources accessible to other threads.
  • Gray
    Gray over 10 years
    That's just part of the spec @Sunny. You need to have the lock to send a notify() so the wait() has to unlock it first.
  • Manan Shah
    Manan Shah over 7 years
    Clear explaination.....
  • Malatesh
    Malatesh over 6 years
    People in the world are like threads on their way they use shared resources like waiting lobby chairs in railway station, petrol fuel station etc. All these people don't know who is waiting for these they acquire and release resource. It is resources announces that they are free and available, not the people , this is why object class has wait() and notify() methods.
  • Gray
    Gray over 6 years
    Your answer is confusing locks and conditions. They are different. wait releases the lock and waits on the condition. Notify releases a thread (or threads) waiting on the condition but does not release the lock.
  • Gray
    Gray over 6 years
    Threads are not created "on an object". Multiple threads do not exist for one object.
  • Ravindra babu
    Ravindra babu over 6 years
    re-phrased sentence.
  • Arefe
    Arefe over 5 years
    Very good explanation and really appreciated.
  • Bhargav Patel
    Bhargav Patel over 4 years
    who is monitor here ? a key or service desk ?