Vinoth Kumar C M
Vinoth Kumar C M

Reputation: 10618

Implementing Producer consumer pattern

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 pattern, but something is going wrong.

I just wrote a skeleton , and the skeleton is not working as expected.

MailProducer.java

public class MailProducer implements Callable<Void>
 {

@Override
public Void call() throws Exception
{
    System.out.println("inside mail Producer");
    System.out.println("Thread executing = " +
                           Thread.currentThread().getName());
    return null;
}

}

MailConsumer.java

public class MailConsumer implements Callable<Void>
{

@Override
public Void call() throws Exception
{
    System.out.println("inside mail consumer");
    System.out.println("Thread executing = " + 
                        Thread.currentThread().getName());
    return null;
}

 }

and finally the Executor

MailExecutor.java

  public class MailExecutor
  {

private static final int NTHREADS = 25;
private static final ExecutorService exec = 
                Executors.newFixedThreadPool(NTHREADS);

public static void main(String[] args)
{
    exec.submit(new MailConsumer());
    exec.submit(new MailProducer());

    System.out.println("inside main");

}

  }

Now when I run the program, I expect it to go back and forth the producer and consumer to keep printing what is written in the respective classes. But instead , the program hangs/does nothing after printing the below lines . What is going wrong ? Am I missing something?

Output ...(Output is not what I had expected. What is going wrong ?)

   inside mail consumer
   inside main
   Thread executing = pool-1-thread-1
   inside mail Producer
   Thread executing = pool-1-thread-2

Upvotes: 3

Views: 2945

Answers (3)

Bohemian
Bohemian

Reputation: 425448

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.

Upvotes: 2

michael667
michael667

Reputation: 3260

  1. You must use loops so that your producer/consumer code is executed more than once.

  2. Your threads do not communicate with each other. Currently you have only two threads being executed. Look at the example in the BlockingQueue javadoc of how to do it.

Upvotes: 0

socha23
socha23

Reputation: 10239

ExecutorService.submit schedules a Runnable or Callable for one execution. Your output shows that MailProducer and MailConsumer both executed once, so everything works like it should.

You should place the inside of your Producer and Consumer methods in loops:

import java.util.concurrent.*;

public class Executor {

    private static final int NTHREADS = 25;
    private static final ExecutorService exec = 
        Executors.newFixedThreadPool(NTHREADS);


    public static void main(String[] args) {
        exec.submit(new MailConsumer());
        exec.submit(new MailProducer());

        System.out.println("inside main");  
    }


    static class MailProducer implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("inside mail Producer");
                System.out.println("Thread executing = " +
                       Thread.currentThread().getName());
            }
       }
    }

    static class MailConsumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("inside mail Consumer");
                System.out.println("Thread executing = " +
                       Thread.currentThread().getName());
            }
       }
    }
}

This gives the output you expect.

Upvotes: 1

Related Questions