Я столкнулся с подобной проблемой, когда моей задачей было отправить сообщение в SQS в течение определенного времени ожидания. Я использовал тривиальную логику его выполнения через другой поток и ожидания его будущего объекта, указав время ожидания. Это дало бы мне исключение TIMEOUT в случае тайм-аутов.
final Future<ISendMessageResult> future =
timeoutHelperThreadPool.getExecutor().submit(() -> {
return getQueueStore().sendMessage(request).get();
});
try {
sendMessageResult = future.get(200, TimeUnit.MILLISECONDS);
logger.info("SQS_PUSH_SUCCESSFUL");
return true;
} catch (final TimeoutException e) {
logger.error("SQS_PUSH_TIMEOUT_EXCEPTION");
}
Но бывают случаи, когда вы не можете остановить выполнение кода другим потоком, и в этом случае вы получаете истинные отрицательные значения.
Например - в моем случае мой запрос достиг SQS, и во время отправки сообщения моя логика кода столкнулась с указанным тайм-аутом. Теперь на самом деле мое сообщение было помещено в очередь, но мой основной поток предположил, что оно не удалось из-за исключения TIMEOUT.
Это тип проблемы, которую можно избежать, а не решить. Как и в моем случае, я избежал этого, предоставив тайм-аут, который будет достаточен почти во всех случаях.
Если код, который вы хотите прервать, находится внутри вашего приложения и не похож на вызов API, тогда вы можете просто использовать
future.cancel(true)
Однако помните, что в документации Java говорится, что она гарантирует, что выполнение будет заблокировано.
"Пытается отменить выполнение этой задачи. Эта попытка потерпит неудачу, если задача уже завершена, уже была отменена или не может быть отменена по какой-либо другой причине. В случае успеха и эта задача не запускается при вызове отмены, эта задача никогда не должна запускаться. Если задача уже запущена, параметр mayInterruptIfRunning определяет, следует ли прерывать поток, выполняющий эту задачу, при попытке остановить задачу. "