Calling wait() on an object causes the thread to wait (be blocked) till it can get hold of this object's lock (Every object has a lock associated with it)
It's actually the synchronized keyword that behaves as you describe. wait() is a completely different ballgame. For a thread to call wait() on an object it must first be the owner of that object's monitor. It is not waiting to acquire the monitor, it already owns it. What it does is release the monitor and then wait until another thread notifies threads waiting on that monitor to wake up either through notify() or notifyAll().
notify() is called on an Object from within a synchronized context when a Thread is about to exit the context. This notifies a Thread that is waiting for this object's lock.
A thread gives up ownership of a monitor when it leaves the critical section or "synchronized context" as you described it. notify() is used to wakeup any object waiting on the monitor. Note this does not mean they were waiting to get ownership of the monitor (they already had it when they called wait() to begin with), simply that they invoked wait() on the same object you're invoking notify() or notifyAll() on. When a thread that's waiting is woken up it will try to get ownership of the monitor and will be blocked until it can. This should be no surprise as wait() was called from a critical section to begin with. Since notify() and notifyAll() can only be called from a thread that owns the monitor it should also be no surprise that any threads woken up can't proceed (they need the monitor) until the current thread relinquishes it.
btw, isnt it also possible to call notify not from within a synchronized block? quite usefull in case you want to tell some other thread to continue running without any synchronization.
No.