It should not make too much difference. take a look at this piece of code
synchronized (obj) {
obj.wait();
obj.doSomething();
}
Suppose 2 threads are waiting on the Object when a third calls notifyAll(). What happens? Both Threads wake up whereupon they have to obtain the Object's monitor before carrying on (the doSomething() call is synchronized on the Object). The VM should fairly give the Threads the lock dependent on their priority.
Conversely suppose that only notify() has been called, then (from the javadoc) the choice of Thread that is awakened is "..arbitrary and occurs at the discretion of the implementation". It is likely that most decent VMs will, again, make this choice fairly and dependent on the Threads' priorities. So not a lot of difference...
As long as the implementation of all .wait()s are done correctly, then using .notifyAll() is much more predictable. Since the choice of the Thread to be awakened is arbitrary and subject to the VM's inner workings, the behavior is not necessarily predictable. This leaves your lock-management up to the run-time environment to manage. Using .notifyAll() however will wake every object waiting on the specific object's monitor every time; this creates a more consistent, and thus predictable, behavior.
In order to rely on this, your .wait()s should all implement the widely-used conditional wait(); that is:
while (condition) {
obj.wait();
}
operations();
notify() wakes up only one waiting thread. You have no idea which thread will be re-awakened, so if you use notify() you must be sure that every waiting thread will be able to continue.
notifyAll() wakes up all waiting threads, so it's far safer to use.
The standard advice is to use notifyAll(). After you get the code working and determine that it's too slow, you can carefully change some notifyAll() calls to notify() as an optimization. At that point, you should write comments that explain the optimization, because if someone adds a wait() on a different condition, it can break the notify() call!