Java Thread How to - Limit ExecutorService for submitted Callable








Question

We would like to know how to limit ExecutorService for submitted Callable.

Answer

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/* w w w .  j a v  a2s . co m*/
public class Main {
  public static void main(final String[] args) {
    new Main();
  }
  ExecutorService ex = Executors.newFixedThreadPool(3);
  public Main() {
    for (int i = 0; i < 10; i++) {
      final int c = i;
      submitTask(new Callable<Object>() {
        @Override
        public Object call() throws Exception {
          long t = System.currentTimeMillis();
          try {
            Thread.sleep(2000);
            System.out.println("Task " + c + " done in "
                + (System.currentTimeMillis() - t) + "ms");
          } catch (Exception e) {
            System.out.println("Task " + c + " aborted after "
                + (System.currentTimeMillis() - t) + "ms");
          }
          return null;
        }
      }, 1000);
    }
    ex.shutdown();
    try {
      ex.awaitTermination(100000, TimeUnit.MILLISECONDS);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  private void submitTask(final Callable<Object> c, final int timeout) {
    TimedFutureTask tft = new TimedFutureTask(c, timeout);
    Future<?> ft = ex.submit(tft.getCallable());
    tft.setFuture(ft);
  }
}
class TimedFutureTask {
  static ScheduledExecutorService canceller = Executors
      .newSingleThreadScheduledExecutor();
  Timer cancelTimer;
  Callable<Object> timedCallable;
  Future<?> f;
  public TimedFutureTask(final Callable<Object> callable, final int timeoutMS) {
    timedCallable = (new Callable<Object>() {
      @Override
      public Object call() throws Exception {
        cancelTimer = new Timer();
        cancelTimer.schedule(new TimerTask() {
          @Override
          public void run() {
            f.cancel(true);
          }
        }, timeoutMS);
        final Object res = callable.call();
        cancelTimer.cancel();
        return res;
      }
    });
  }
  public Callable<Object> getCallable() {
    return timedCallable;
  }
  public void setFuture(final Future<?> future) {
    f = future;
  }
}

The code above generates the following result.