Como posso terminar as tarefas que atingiram o tempo limite no multithreading?

Preciso criar uma biblioteca na qual terei métodos síncronos e assíncronos.

executeSynchronous() - espera até que eu tenha um resultado, retorna o resultado.executeAsynchronous() - retorna um futuro imediatamente, que pode ser processado depois que outras coisas forem feitas, se necessário.

Lógica principal da minha biblioteca

O cliente usará nossa biblioteca e chamará passandoDataKey objeto construtor. Em seguida, construiremos um URL usando esseDataKey objeto e faça uma chamada de cliente HTTP para esse URL, executando-o e depois que recebermos a resposta novamente como uma String JSON, enviaremos essa String JSON de volta ao nosso cliente, criandoDataResponse objeto. Algum cliente ligaráexecuteSynchronous() e alguns podem ligarexecuteAsynchronous() é por isso que preciso fornecer dois métodos separadamente na minha biblioteca.

Interface:

public interface Client {

    // for synchronous
    public DataResponse executeSynchronous(DataKey key);

    // for asynchronous
    public Future<DataResponse> executeAsynchronous(DataKey key);
}

E então eu tenho o meuDataClient que implementa o acimaClient interface:

public class DataClient implements Client {

    private RestTemplate restTemplate = new RestTemplate();
    private ExecutorService executor = Executors.newFixedThreadPool(10);

    // for synchronous call
    @Override
    public DataResponse executeSynchronous(DataKey key) {
        DataResponse dataResponse = null;
        Future<DataResponse> future = null;

        try {
            future = executeAsynchronous(key);
            dataResponse = future.get(key.getTimeout(), TimeUnit.MILLISECONDS);
        } catch (TimeoutException ex) {
            PotoLogging.logErrors(ex, DataErrorEnum.TIMEOUT_ON_CLIENT, key);
            dataResponse = new DataResponse(null, DataErrorEnum.TIMEOUT_ON_CLIENT, DataStatusEnum.ERROR);
            // does this look right the way I am doing it?
            future.cancel(true); // terminating tasks that have timed out.
        } catch (Exception ex) {
            PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
            dataResponse = new DataResponse(null, DataErrorEnum.CLIENT_ERROR, DataStatusEnum.ERROR);
        }

        return dataResponse;
    }

    //for asynchronous call
    @Override
    public Future<DataResponse> executeAsynchronous(DataKey key) {
        Future<DataResponse> future = null;

        try {
            Task task = new Task(key, restTemplate);
            future = executor.submit(task); 
        } catch (Exception ex) {
            PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
        }

        return future;
    }
}

Classe simples que executará a tarefa real:

public class Task implements Callable<DataResponse> {

    private DataKey key;
    private RestTemplate restTemplate;

    public Task(DataKey key, RestTemplate restTemplate) {
        this.key = key;
        this.restTemplate = restTemplate;
    }

    @Override
    public DataResponse call() {
        DataResponse dataResponse = null;
        String response = null;

        try {
            String url = createURL();
            response = restTemplate.getForObject(url, String.class);

            // it is a successful response
            dataResponse = new DataResponse(response, DataErrorEnum.NONE, DataStatusEnum.SUCCESS);
        } catch (RestClientException ex) {
            PotoLogging.logErrors(ex, DataErrorEnum.SERVER_DOWN, key);
            dataResponse = new DataResponse(null, DataErrorEnum.SERVER_DOWN, DataStatusEnum.ERROR);
        } catch (Exception ex) {
            PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
            dataResponse = new DataResponse(null, DataErrorEnum.CLIENT_ERROR, DataStatusEnum.ERROR);
        }

        return dataResponse;
    }

    // create a URL by using key object
    private String createURL() {
        String url = somecode;
        return url;
    }
}

Declaração do problema: -

Quando comecei a trabalhar nesta solução, não estava finalizando as tarefas que atingiram o tempo limite. Eu estava relatando o tempo limite para o cliente, mas a tarefa continua em execução no pool de threads (ocupando potencialmente um dos meus 10 threads limitados por um longo tempo). Pesquisei on-line e descobri que posso cancelar minhas tarefas que atingiram o tempo limite usandocancel emfuture como mostrado abaixo -

future.cancel(true);

Mas eu queria ter certeza, parece correto do jeito que estou fazendo no meuexecuteSynchronous método para cancelar as tarefas que atingiram o tempo limite?

Desde que eu estou ligandocancel() noFuture o que impedirá a execução se as tarefas ainda estiverem na fila, por isso não tenho certeza do que estou fazendo ou não? Qual é a abordagem correta para fazer isso?

Se existe uma maneira melhor, alguém pode dar um exemplo disso?

questionAnswers(1)

yourAnswerToTheQuestion