Skip to content
Advertisement

service.shutdownNow() not killing the thread

In my application im spawning a single thread executor and in the thread I’m doing logic of loading ML models/predictions. If any of the logic exceeds the time-limit(4 minutes), I’m shutting down the thread.

But when the application is up, when time out happens, I’m able to see logs of threads getting shut down. But the process(Prediciton logic) continues to execute.

Code snippet for creating the thread

            ExecutorService service = Executors.newSingleThreadExecutor();
            Future<Object> prediction = null;
            try {
              prediction = service.submit(() -> {
                // Execute the requested Document Prediction Engine against the XML Document.
                return executeEngine(tenantId, appId, engine, document, predictionParams == null ? new HashMap<>() : new HashMap<>(predictionParams)).get();
              });
              predictionResult = prediction != null ? (PredictionResult) prediction.get(Long.parseLong(System.getProperty(IDR_INTERNAL_TIMEOUT, "30000")),
                      TimeUnit.MILLISECONDS) : null;
              } catch (TimeoutException e) {
              if (prediction != null) {
                LOGGER.debug("Task was cancelled with a {} status", (prediction.cancel(true) ? " successful" : " failure"));
              }
              ExpenseMetrics.internalPredictionTimeout.inc();
              String message = "Prediction took more than allowed milliseconds: " + Long.parseLong(System.getProperty(IDR_INTERNAL_TIMEOUT, "30000")) +
                " fileName: "+ documentFile.getFileName();
              
              if (service != null && !service.isShutdown()) {
                service.shutdownNow();
              }
              service = null;
              throw new IDRExmClientException(message, requestId, ErrorCode.INTERNAL_TIMEOUT);
            } 
            if (service != null && !service.isShutdown()) {
              service.shutdownNow();
            }
            service = null;

Code snippet for Prediction logic and timeout

List<Callable<Void>> taskList = new ArrayList<Callable<Void>>();
taskList.add(callable1);
taskList.add(callable2);    
ExecutorService executor = null;
List<Future<Void>> futures = null;
long s = System.currentTimeMillis();
try {
  executor = Executors.newFixedThreadPool(THREAD_POOL);
  futures = executor.invokeAll(taskList);    
  executor.shutdown();
  if (!executor.awaitTermination(TOLERANCE_MINUTES, TimeUnit.MINUTES)) {                
    LOGGER.warn("Document predict thread took more than {} minutes to shutdown", TOLERANCE_MINUTES);
    executor.shutdownNow();
  }
} catch (InterruptedException iex) {
  LOGGER.error("Document predict thread was interrupted", iex);
} finally {
  cancelFutures("Predict", futures);
  LOGGER.debug("Document predict thread took: {}", (System.currentTimeMillis() - s));
  if (executor != null && !executor.isShutdown()) {        
    executor.shutdownNow();
  }      
}
executor = null;

Advertisement

Answer

from the Oracle documentation of the method shutDownNow() :

There are no guarantees beyond best-effort attempts to stopprocessing actively executing tasks. For example, typicalimplementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.

you can see this answer it may help you: ExecutorService is not shutting down

Advertisement