Saturday, April 12, 2014

Throttle task submission in Java - Simple solution

JDK provides a convenient java.util.concurrent.Executors factory with useful methods to return various java.util.concurrent.Executor implementation instance pre-configured with commonly used settings. However, there is no implementation or configuration available for an implementation that throttles task submission. Here I provide my take on a very simple solution for this requirement.

private void submitTasks(List tasksList) {
  final ThreadPoolExecutor executor = new ThreadPoolExecutor(MIN_POOL_SIZE,
                                                             MAX_POOL_SIZE,
                                                             60L,
                                                             TimeUnit.SECONDS,
                                                             new LinkedBlockingQueue());
  for (Runnable task : tasksList) {
    while (executor.getQueue().size() > MAX_Q_SIZE) {
      // Throttle for WAIT_FOR_SECONDS seconds if queue is full
      try {
        log.info("Waiting " + WAIT_FOR_SECONDS + " seconds as Queue size is: " + executor.getQueue().size());
        Thread.sleep(WAIT_FOR_SECONDS * 1000);
      } catch (InterruptedException e) {
        // Ignore
      }
    }
    executor.execute(task);
  }
  // inform the executor there are no more tasks
  executor.shutdown();
}

Instead of using the factory to get a pre-configured executor, I create my own ThreadPoolExecutor using a LinkedBlockingQueue. This allows us access to the underlying queue for the throttling feature. Before submitting the task, I check if the current queue size is greater than a certain size and if so, then wait for a configured time repeatedly till the queue is smaller.
This implementation is very useful for the scenarios where you have lots of short running tasks that need to be processed by a fixed small number of threads.

No comments:

LinkWithin

Related Posts Plugin for WordPress, Blogger...