You can find the answer in the Java API documentation of method wait() in class Object - look it up.
You can only call wait() when the current thread owns the monitor of the object on which you call wait(). As the API documentation says, inside wait() the monitor will be temporarily released, and when wait() returns it is obtained again.
So while the thread is waiting inside the wait() method, it has released the lock on the object.
Arnb, you are correct that if the Calculator runs first and acquires the lock, then none of the Readers will be able to acquire that lock until after the Calculator finishes. Which will create some problems, as discussed in the very next section of the book (assuming you've got the most recent edition, for SCJP 1.5).
Note that as far as I'm aware, both the 1.4 and 1.5 versions of this book have a different main() method than you showed:
The calculator is started after the readers, which makes it more likely that the readers will acquire locks and wait() before the calculator. It's not guaranteed, however. Which is why they wait() should really be inside a loop which checks some condition, as discussed in the next section of the book. The code sample shown is not intended to be perfect; it demonstrates some characteristics of threaded code, but not all of them. Continue reading to learn more. [ July 27, 2007: Message edited by: Jim Yingst ]