Как я могу завершить Задачи, которые истекли в многопоточности?

Мне нужно сделать библиотеку, в которой у меня будут синхронные и асинхронные методы.

executeSynchronous() - ждет, пока у меня не появится результат, возвращает результат.executeAsynchronous() - немедленно возвращает Future, который может быть обработан после выполнения других действий, если это необходимо.

Основная логика моей библиотеки

Клиент будет использовать нашу библиотеку и позвонит ей, передавDataKey застройщик объекта. Затем мы создадим URL, используя этоDataKey выполнить объект и выполнить HTTP-вызов клиента на этот URL, выполнив его, и после того, как мы получим ответ обратно в виде строки JSON, мы отправим эту строку JSON нашему клиенту в том виде, как он есть, создавDataResponse объект. Какой-то клиент позвонитexecuteSynchronous() а некоторые могут позвонитьexecuteAsynchronous() вот почему я должен предоставить два метода отдельно в моей библиотеке.

Интерфейс:

public interface Client {

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

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

И тогда у меня есть мойDataClient который реализует вышеупомянутоеClient интерфейс:

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;
    }
}

Простой класс, который будет выполнять актуальную задачу:

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;
    }
}

Постановка задачи:-

Когда я начал работать над этим решением, я не прекращал выполнение заданий, срок действия которых истек. Я сообщал клиенту об истечении времени ожидания, но задача продолжает выполняться в пуле потоков (потенциально занимающих один из моих ограниченных 10 потоков в течение длительного времени). Поэтому я провел некоторые исследования в Интернете и обнаружил, что могу отменить свои задачи, для которых истек срокcancel наfuture как показано ниже -

future.cancel(true);

Но я хотел убедиться, выглядит ли это правильно, как я делаю в моемexecuteSynchronous способ отменить задачи, которые получили тайм-аут?

Так как я звонюcancel() наFuture что остановит его выполнение, если задачи все еще находятся в очереди, поэтому я не уверен, что я делаю правильно или нет? Какой правильный подход для этого?

Если есть какой-то лучший способ, то кто-нибудь может привести пример для этого?

Ответы на вопрос(1)

Ваш ответ на вопрос