I am trying to write a mail utility that places mails in a queue, and it is later consumed by a consumer thread.
I am trying to implement a typical producer-consumer
You are missing the shared queue. Without the queue, you have nothing.
Producers put work onto the queue. Consumers take work off the queue. Use a BlockingQueue, whose put() and take() methods are blocking calls. Running producers and consumers in separate threads allows them to safely block while calling these methods.
Neither the producers nor the consumers need to be Callable; Runnable will do. Using an Executor to tie it all together is a good idea.