<p>Someone at work just asked for the reasoning behind having to wrap a wait inside a synchronized.</p>

<p>Honestly I can't see the reasoning.  I understand what the javadocs say--that the thread needs to be the owner of the object's monitor, but why?  What problems does it prevent?  (And if it's actually necessary, why can't the wait method get the monitor itself?)</p>

<p>I'm looking for a fairly in-depth why or maybe a reference to an article.  I couldn't find one in a quick google.</p>

<p>Oh, also, how does thread.sleep compare?</p>

<p>edit: Great set of answers--I really wish I could select more than one because they all helped me understand what was going on.</p>

If the object does not own the object monitor when it calls Object.wait(), it will not be able to access the object to setup a notify listener until the the monitor is released. Instead, it will be treated as a thread attempting to access a method on a synchronized object.
Or to put it another way, there is no difference between:
```
```
public void doStuffOnThisObject()
```
```
and the following method:
```
```
public void wait()
```
```
Both methods will be blocked until the object monitor is released. This is a feature in Java to prevent the state of an object from being updated by more than one thread. It simply has unintended consequences on the wait() method.
Presumably, the wait() method is not synchronized because that could create situations where the Thread has multiple locks on the object. (See
Java Language Specifications/Locking
for more info on this.) Multiple locks are a problem because the wait() method will only undo one lock. If the method were synchronized, it would guarantee that only the method's lock would be undone while still leaving a potential outer lock undone. This would create a deadlock condition in the code.
To answer your question on Thread.sleep(), Thread.sleep() does not guarantee that whatever  condition you are waiting on has been met. Using Object.wait() and Object.notify() allows a programmer to manually implement blocking. The threads will unblock once a notify is sent that a condition has been met. e.g. A read from disk has finished and data can be processed by the thread. Thread.sleep() would require the programmer to poll if the condition has been met, then fall back to sleep if it has not.