Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I kill a Java Future?

The service I'm working on uses a Future to run multiple tasks in parallel; each task can take up to a minute to complete. However, it seems the external lib is buggy, since in some occasions (2% of the time) it doesn't return. In those cases I would like to give a 2-minute wait time, and if it hasn't returned, I would like to kill the future and re-schedule again later (it will succeed eventually).

How do I kill the Future?

  private void run() {
    ExecutorService queue = Executors.newFixedThreadPool(1);

    Future<Integer> f = queue.submit(new MyTask());
    Thread.sleep(500);

    try {
      Integer r = f.get(120, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
      e.printStackTrace();
      f.cancel(true);
    }

    // Bad future still running here and I need it dead.

  }

  private class MyTask implements Callable<Integer> {
    private ExternalLibrary extlib = new ExternalLibrary();

    @Override
    public Integer call() throws Exception {
      // step 1 - do a few things

      // step 2 - process data
      Integer val = this.extlib.doSomething(); // here's the problem!

      // step 3 - do other things

      return val;
    }

  }

I can see the external lib running and consuming CPU (for 24 hours)... doing nothing. It's a simple task that should never take more than 60 seconds to complete its work.

So far, I'm killing the whole JVM once a day to get rid of this issue, but I'm sure there must be a better way. I wonder how app servers (Tomcat, JBoss, Weblogic, etc.) do it with rogue processes.

like image 221
Joe DiNottra Avatar asked Jun 25 '26 02:06

Joe DiNottra


1 Answers

Even if you could kill the future hanging in the buggy library, this does likely not solve your problem. The library might still have acquired some resource which will not be properly clean up. This might be memory allocations, open file handles or even monitors leaving some internal data structures in an inconsistent state. Eventually you will likely be back at the point where you have to restart your JVM.

There's basically two options: Fix or isolate it.

  1. Fix: try to get the library fixed. If this is not possible,
  2. isolate: isolate the library into a external service your application depends on. E.g. implement a REST API for calling the library and wrap everything up into a Docker image. Automate restarting of the Docker container as needed.
like image 142
michid Avatar answered Jun 26 '26 14:06

michid