-1

For conventional Producer-Consumer problem, we can use ExecutorService as queue. What are disadvantages of it? Is it less efficient? Because creation of thread is costly.

executor = Executors.newFixedThreadPool(90);
// This will be called many times concurrently
public void processObjectsWithFixedSetOfThreads(Foo objectToProcess) {
   //Create a new thread and submit (executor is of fixed size hence extra tasks will be queued)
   executor.submit(new ObjectProcessorWorker(objectToProcess));
}

class ObjectProcessorWorker implements Runnable() {
  public ObjectProcessorWorker(Foo obj) {
     this.obj = obj;
  }

  public void run() {
     longRunningProcess(obj);
  }

}

Why BlockingQueue is recommended for Producer-Consumer problem however it can be done without that too (As shown above)?

EDIT

Many people are not getting the difference because ThreadPoolExecutor internally maintains the BlockingQueue.

In a biscuit factory there is a task of wrapping biscuits. If I am its owner I have two ways to speed up wrapping task.

  1. Put biscuits and wrapper on assembly line have 10 workers doing work of wrapping.

    I -> queue.put(biscuits, wrapper)

    Worker -> queue.take()

  2. Creating a task of wrapping biscuits putting it on a assembly line, and let the 10 workers do that.

    I -> new Task(biscuits, wrapper)

    Worker -> task = queue.take(); do(task);

I am asking the disadvantages of the later one.

Nilesh
  • 2,089
  • 3
  • 29
  • 53
  • 1
    They're not really the same thing at all. The executor service is running things from a queue (it has a blocking queue internally, holding the submitted tasks); it's not the queue itself. – Andy Turner Aug 09 '16 at 09:54
  • @AndyTurner I have added an edit. – Nilesh Aug 09 '16 at 12:20

2 Answers2

1

Whenever you define ThreadPoolExecutore.. as shown bellow

ExecutorService threadPoolExecutor =
        new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                keepAliveTime,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>()
                );

If less than corePoolSize threads are created in the the thread pool when a task is delegated to the thread pool, then a new thread is created, even if idle threads exist in the pool.

If the internal queue of tasks is full, and corePoolSize threads or more are running, but less than maximumPoolSize threads are running, then a new thread is created to execute the task

Now if you have defined blocking queue... than after corePoolSize , it will add new threads in to queue... till the capacity of queue reached. And after overflowing queue, it will generate new threads upto maximumPoolSize.

Don't know what is dis advantage of using ExecutorService as queue. I dont think there is any disadvantages.

Nirav Chhatrola
  • 482
  • 4
  • 15
0

When you create a ThreadPoolExecutor using Executors.newFixedThreadPool(int), you are creating a BlockingQueue:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

As such, you're not doing it "without" a blocking queue if you a thread pool created in this way; it's just hidden from you.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • I agree that BlockingQueue is created internally. But when executing `new Runnable()` there might be overhead due to creation of thread. However if I create `BlockingQueue` then thread creation never happens. – Nilesh Aug 09 '16 at 10:22
  • Of course no thread is created: a queue doesn't create threads, it's just a queue. – Andy Turner Aug 09 '16 at 10:22
  • "without Blocking Queue" means using internal BQ. – Nilesh Aug 09 '16 at 10:24