This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
If I use threadB.wait() in threadA and in threadB I do not call notify(), when the run() method of threadB finishes, then the threadA continues like I had call notify() in threadB...
This is an implementation detail -- which is of course, subject to change.
The join() method is implementated internally with the wait()/notifyAll(). A join() method call on the thread object does a wait() on the thread object. When the thread finishes, some of things that it does are, set the alive flag to indicate that it is not, and send a notifyAll() to all threads doing a join().
Obviously, you are not using the join() method, but you are waiting on the same notification object used by the join() method.