Question

I have to schedule some tasks at some interval and have to kill the task which is taking more than specified time.

code:

public class ExecutorMain {
  public static void main(String[] args) throws InterruptedException, ExecutionException,        TimeoutException {
    ScheduledThreadPoolExecutor scheduledExecutorService = new     ScheduledThreadPoolExecutor(2);
    scheduledExecutorService.scheduleAtFixedRate(new ShortTask(2), 0, 3, TimeUnit.SECONDS);
    scheduledExecutorService.scheduleAtFixedRate(new LongTask(1), 0, 10, TimeUnit.SECONDS);
  }
}

class ShortTask implements Runnable {
  private int id;
  ShortTask(int id) {
    this.id = id;
  }
  public void run() {
    try {
        Thread.sleep(1000);
        System.out.println("Short Task with id "+id+" executed by "+Thread.currentThread().getId());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
  }
}

class LongTask implements Runnable {
  private int id;
  LongTask(int id) {
    this.id = id;
  }
  public void run() {
    try {
        Thread.sleep(6000);
        System.out.println("Long Task with id "+id+" executed by "+Thread.currentThread().getId());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
  }
}

In the above example, i want to kill the task which is taking more than 5 secs(LongTask) without disturbing the execution of other tasks. what is the best way to achieve this?

Was it helpful?

Solution 2

After much thought and a lot of search, going with the below approach.

Solution from : https://stackoverflow.com/a/808367/3048186

public class ExecutorMain {
   public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
      ScheduledThreadPoolExecutor scheduledExecutorService = new ScheduledThreadPoolExecutor(2);
      scheduledExecutorService.scheduleAtFixedRate(new ShortTask(1, 5000), 0, 3, TimeUnit.SECONDS);
      scheduledExecutorService.scheduleAtFixedRate(new ShortTask(2, 5000), 0, 3, TimeUnit.SECONDS);
      scheduledExecutorService.scheduleAtFixedRate(new LongTask(1, 5000), 0, 10, TimeUnit.SECONDS);
      scheduledExecutorService.scheduleAtFixedRate(new LongTask(2, 5000), 0, 10, TimeUnit.SECONDS);
   }
}

class Worker extends Thread {
  private final Process process;
  private Integer exit;
  String id;
  Worker(Process process, String id) {
    this.process = process;
    this.id = id;
  }
  public void run() {
    try {
        exit = process.waitFor();
    } catch (InterruptedException ignore) {
        //NOOP
    }
}

public Integer getExit() {
    return exit;
  }
}

class ShortTask implements Runnable {
  private int id;
  private long timeOut;
  ShortTask(int id, long timeOut) {
    this.id = id;
    this.timeOut = timeOut;
  }
  public void run() {

    long start = System.currentTimeMillis();

    Runtime runtime = Runtime.getRuntime();
    Process process = null;
    try {
        process = runtime.exec("sleep 1s");
    } catch (IOException e) {
        System.out.println("ShortTask IOE");
    }
    Worker worker = new Worker(process, "short task"+id);
    worker.start();
    try {
        worker.join(timeOut);
        long total = System.currentTimeMillis()-start;
        //If time out, exit code would be null
        System.out.println(" Short task id :"+id+" Exit Code : " +worker.getExit()+" thread id "+Thread.currentThread().getId()+" in time "+total);
    } catch(InterruptedException ex) {
        worker.interrupt();
        Thread.currentThread().interrupt();
    } finally {
        if(process != null) {
            process.destroy();
        }
    }
}
}

class LongTask implements Runnable {
  private int id;
  private long timeOut;
  LongTask(int id, long timeOut) {
    this.id = id;
    this.timeOut = timeOut;
  }
  public void run() {

    long start = System.currentTimeMillis();

    Runtime runtime = Runtime.getRuntime();
    Process process = null;
    try {
        process = runtime.exec("sleep 60s");
    } catch (IOException e) {
        System.out.println("LongTask IOE");
    }
    Worker worker = new Worker(process, "long task"+id);
    worker.start();
    try {
        worker.join(timeOut);
        long total = System.currentTimeMillis() - start;
        //If time out, exit code would be null
        System.out.println(" Long Task id :"+id+" Exit Code : " +worker.getExit()+" thread id "+Thread.currentThread().getId()+" in time "+total);
    } catch(InterruptedException ex) {
        worker.interrupt();
        Thread.currentThread().interrupt();
    } finally {
        if(process != null) {
            process.destroy();
        }
    }
  }
}

OTHER TIPS

Use ScheduledFuture to handle it. Try,

final ScheduledFuture<?> longTaskHandler=
          scheduledExecutorService.scheduleAtFixedRate(new LongTask(1), 
           0, 10, TimeUnit.SECONDS);

scheduledExecutorService.schedule(new Runnable() {
        public void run() {
            longTaskHandler.cancel(true);
        // This will cancel your LongTask after 5 sec without effecting ShortTask
        }
    }, 5, TimeUnit.SECONDS);

For details, look at this docs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top