Looks like you are getting confused between synchronized code and locks. Let me answer your questions one by one.
(1) Why does Java make it so complex? Actually its the other way...Java has made it simpler. You don't have to explicitly create a mutex. Any thread that is entering a synchronized block will create one automatically. Remember, if you programatically created the mutex( in Java they are called locks ) you will also have to take care of unlocking it upon abnormal program termination. In otherwords, you not only create a mutex, but will also have to manage assuming all possible paths of execution. I personally feel that is a programming nightmare and is
very error prone. In Java any thread if dies abnormally, it relinquishes the locks!
(2) Why do I have to use synchronize around wait and notify? It seems redundant. Usually wait and notify are used in situations where there are multiple threads competing for a shared resource. These threads by themselves are executing a synchronzied block( or waiting for the lock ). The "synchronzied" only gives you basic level of protection against concurrent access. When you have multiple threads, just synchronization will not do the job. It is very easy to write a program that will go into a race-condition or a dead-lock condition if you don't take care of which thread gets what and when. That is when wait and notify
complements the synchronization mechanism.
(3) Since synchronize only admits one thread, why are not notify and notifyAll identical? Firstly notify wakes up one waiting thread( noway to tell which one ) and notifyAll wakes up all waiting threads. Again, synchronziation is not replacement for wait/notify mechanism. I can only say since these two notification methods were written because they are different from one another. There will be situations where you will not be able to replace notifyAll call with a notify call.
(4) When I use wait and aquire ownership of a resource, when is it released? You will own a resource soon after entering in to the synchronized block. There are locks on classes and objects. You can have a local synchronized block with an explicit object reference OR a synchronized method which locks the 'this' object. No matter how the lock was obtained, it will be released( ownership relinquished ) soon after the synchronized block terminates normally or abnormally.
(5) Do wait/notify implement the concept of mutex ownership? Apparently not, I don't see any calls by the name of release. I think I have partially answered this in question (1). Java keeps track of all locked resources and their locks( mutexes ) and release them when appropriate. Just as you cannot see an object getting locked, you will not have to make explicit calls to unlock it. It makes our job easier and reduces programmatic error conditions.
Hope this helps. You might want to stop by the
Threads and Synchronization where these things are discussed regularly and in greater depths!
Ajith