Your problem is that you are extending Thread, then calling wait() on the Thread object. There is un-documented behavior regarding Thread and what happens when a Thread comes to an end. The part that is messing with your application is that when a Thread dies, it calls notifyAll() on the Thread object itself, so any wait()ers are woken up. This is not documented, so it can't be relied on - it is a side effect of some Thread implementation detail.
As a result, I use this as one of those reasons why it usually does NOT make sense to extend Thread. You should instead make both Reader1 and Calculator implement Runnable, not extend Thread. Then add start() methods which create new Threads and start them. Example: