The recommended approach is generally to set a boolean flag (
finished or similar) on threads that will need to be terminated and then loop
while(!finished). (Note that the flag generally needs to be
volatile so that the thread will see changes.) If the thread is expected to be blocking, then you can
interrupt() it to restart its waiting loop.
The overall approach you're taking seems to be out of date, though. The
BlockingQueue implementations were designed specifically to ease producer-consumer implementations, and many such problems can be more effectively handled by using an
Executor and firing off tasks to it as they come in instead of manually queuing and polling.