Because, you wait on a given Object (or specifically, its monitor) to use this functionality.
I think you may be mistaken on how these methods work. They're not simply at a Thread-granularity level, i.e. it is not a case of just calling wait()
and being woken up by the next call to notify()
. Rather, you always call wait()
on a specific object, and will only be woken by calls to notify
on that object.
This is good because otherwise concurrency primitives just wouldn't scale; it would be equivalent to having global namespaces, since any calls to notify()
anywhere in your program would have the potential to mess up any concurrent code as they would wake up any threads blocking on a wait()
call. Hence the reason that you call them on a specific object; it gives a context for the wait-notify pair to operate on, so when you call myBlockingObject.notify()
, on a private object, you can be sure that you'll only wake up threads that called wait methods in your class. Some Spring thread that might be waiting on another object will not be woken up by this call, and vice versa.
Edit: Or to address it from another perspective - I expect from your question you thought you would get a handle to the waiting thread and call notify()
on that Thread to wake it up. The reason it's not done this way, is that you would have to do a lot of housekeeping yourself. The thread going to wait would have to publish a reference to itself somewhere that other threads could see it; this would have to be properly synchronized to enforce consistency and visibility. And when you want to wake up a thread you'd have to get hold of this reference, awaken it, and remove it from wherever you read it from. There's a lot more manual scaffolding involved, and a lot more chance of going wrong with it (especially in a concurrent environment) compared to just calling myObj.wait()
in the sleeping thread and then myObj.notify()
in the waker thread.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…