简体   繁体   中英

Why wait, notify and notifyAll are methods in Object class not like Cloneable

Recently, I was asked in interview why wait , notify , and notifyAll are used. I explained them.

After that they asked me to assume an application is always single threaded. Is it really required? My answer was no.

Then, they asked why is design like wait , notify , and notifyAll are methods on the Object class. Why doesn't Java have an interface and these methods are in that interface and which ever class wants to implement it can use it. So, I was kind of stuck and unable to think over this design. Can anyone please sow light over this?

JVM uses OS-level threads. That means that each concrete JVM for each concrete OS handles threads differently. And these methods are not only implemented in Object class, they are marked as native , which kind of means that the are implemented in system layer of JVM.

And if those methods were in some interface, that would mean that anybody can redefine them.

Wait and notify and notifyAll is not just normal methods or synchronization utility, more than that they are communication mechanism between two threads in Java. And Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized. Remember synchronized and wait notify are two different area and don't confuse that they are same or related. Synchronized is to provide mutual exclusion and ensuring thread safety of Java class like race condition while wait and notify are communication mechanism between two thread.

Then, they asked why is design like wait , notify , and notifyAll are methods on the Object class. Why doesn't Java have an interface and these methods are in that interface and which ever class wants to implement it can use it.

All of these methods are implemented in native code and they integrate closely with the synchronized block that wraps them. They are part of the Java language definition and have specific behaviors that programmers rely on. It would not be appropriate for them just to be interface methods that any object would implement.

When one object calls obj.wait(); on another object, it doesn't have to worry about the implementation of wait . It needs to make sure that it has a mutex lock on that object so it can make critical updates to it or other storage and if the wait method was implemented by the object itself, then that object could violate the language requirements and, for example, allow multiple threads into the protected block at the same time. A thread can synchronize and call wait / notify / notifyAll on another object or not without having to worry about whether or not that object has implemented those methods appropriately. By making them final methods on Object the behavior will work the same regardless of the object type or local implementation.

Also, as I mentioned, wait / notify / notifyAll are integrated closely with the surrounding synchronized block. When a thread is blocked in wait() the surrounding synchronized lock is released so that other threads can get access to the protected block. This coordination would not be possible if the wait() was just a simple method call without other strange language features.

This reminds me of my other answer here: Concept behind putting wait(),notify() methods in Object class

It was a design goal from the start that Java programs would be multithreaded. Remember the plan was for Java to make embedded programming less intimidating, the whole serverside web application thing (leading to the commoditization of Sun's core business) was an accident.

Since the goal was to enable creating embedded applications that would talk to other devices, it had to be multithreaded in order to be network-friendly and event-driven. But writing efficient multithreaded servers wasn't high on the list for java.

Java didn't have ReentrantLock or nonblocking i/o for a long time. Initially the main data structures available were Vector, Hashtable, and StringBuffer (all of which had synchronized on all public methods). From that choice it seems like the goal was good-enough, as opposed to being as efficient as possible. Later on it was clear Java needed to be more efficient for the use case of server applications and 1.2 introduced equivalents of Vector and Hashtable that were unsynchronized. This seemed like an afterthought, a course adjustment made once it was apparent Java had a new role it wasn't previously designed for.

If Java had stayed in the niche it was created for then possibly intrinsic locks might have been adequate. It seems the initial plan was for intrinsic locks only, so that the lock might as well be wired into the Object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM