#java #future #executorservice #timeoutexception
Вопрос:
Я использую следующий код:
import java.util.concurrent
senderSocket.send(datagramPacket);
while (!test(packetToSend)) {
senderSocket.send(datagramPacket);
}
public boolean test(Packet sentPacket) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Packet> callable = new Callable() {
public Packet call() throws Exception {
//do operations you want
Packet responsePacket = Helper.recievePacket(rSocket);
while (responsePacket.isCorrupt() || responsePacket.getSequence() != sentPacket.getSequence()) {
responsePacket = Helper.recievePacket(rSocket);
}
System.out.println(new String(responsePacket.getData(),UTF_8));
return responsePacket;
}
};
Future<Packet> future = executor.submit(callable);
try {
future.get(1000, TimeUnit.MILLISECONDS);
return true;
} catch (TimeoutException e) {
System.out.println("time-out");
executor.shutdown();
return false;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return false;
}
Приведенный выше код работает нормально, если нет тайм-аута. Но как только он создает исключение timeoutexception, все дальнейшие вызовы автоматически заканчиваются, даже если я получаю ответ. Я попытался увеличить время ожидания с 1 секунды до 2 секунд. Он снова продолжает выбрасывать исключение TimeoutException
Комментарии:
1. Отправьте тот же вызов снова и назначьте
future
результат.2. @LouisWasserman Я могу сделать
future = executor.submit(callable);
внутри блока catch, но теперь в случае исключения TimeoutException такое поведение больше не повторится. В принципе, когда происходит тайм-аут, это должно повторитьсяsenderSocket.send(datagramPacket); future = executor.submit(callable);
, я не уверен, как делать такие вещи3. Вы должны сделать цикл, который будет продолжаться до тех пор, пока не добьетесь успеха.
4. @LouisWasserman Спасибо за это. У меня кое-что работает. Но я начинаю вести себя странно.
future. get(1000, TimeUnit.MILLISECONDS);
Как только время будущего истечет. Каждый раз время поджимает. Не знаю, почему это может быть так. Я только что обновил код в OP. Логика работает. Но единственная проблема заключается в том, когда происходит тайм-аут. Он просто каждый раз создает исключение timeoutexception5. Если время ожидания истекло, значит, вы не получили ожидаемого ответа. Он все еще сидит в розетке? Может ли удаленный сервер обработать другой запрос, пока ответ еще не получен? Я бы посмотрел, что происходит в цикле «пока» в задаче.
Ответ №1:
Почему бы вам не проверить с помощью futureisDone(). Это неблокирующий api. Если он вернет значение true, вы можете вызвать future.get()
Ответ №2:
Будущее Java упустило некоторые полезные методы, такие как onComplete().
Но мы можем написать его сами.
public static void main(String[] args) throws InterruptedException, ExecutionException {
Future<String> f = null;
onComplete(f, System.out::println);
}
static <T> void onComplete(Future<T> f, Consumer<T> callBack) throws InterruptedException, ExecutionException {
while(!f.isDone()) {}
callBack.accept(f.get());
}