Search code examples
javaconcurrencyjava.util.concurrent

Best practice for executing large number of tasks


Below code creates large number of runnable object in loop, even only 5 treads are there to process the tasks. Is there any way so that at any moment only 5 runnable object will be present in memory not the total number of tasks( 100000).

ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10000; i++) {
    Runnable worker = new WorkerThread("" + i);
    System.out.println("ExecutorExample.main()");
    executor.execute(worker);
}

Solution

  • The requirement that at any moment only 5 runnable object will be present in memory is too restrictive. When a task finishes, there would be no next task to run, and some time would be spend to create another task. Better to have 5 runnung tasks and 5 waiting in a line. In order to restrict the number of the tasks in the queue, use a BlockingQueue of fixed size for runnables, e.g.

    ThreadPoolExecutor executor = new ThreadPoolExecutor(
         5, 5,
         10L, TimeUnit.MILLISECONDS,
         new LinkedBlockingQueue<Runnable>(5)
    )
    

    UPDT To avoid RejectedExecutionException, add RejectedExecutionHandler, as proposed in https://stackoverflow.com/a/3518588/1206301:

    RejectedExecutionHandler block = new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                try {
                    executor.getQueue().put(r);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        executor.setRejectedExecutionHandler(block);