jestem obliczania przyszłość ma limitu czasu w oczekiwaniu na wydarzenia szeregowego wydarzy:Jak zatrzymać czas oczekiwania przyszłego
Future<Response> future = executor.submit(new CommunicationTask(this, request));
response = new Response("timeout");
try {
response = future.get(timeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (InterruptedException | TimeoutException e) {
future.cancel(true);
log.info("Execution time out." + e);
} catch (ExecutionException e) {
future.cancel(true);
log.error("Encountered problem communicating with device: " + e);
}
Klasa CommunicationTask
wdrożyła interfejs Observer
wysłuchać na zmianę z port szeregowy.
Problem polega na tym, że odczyt z portu szeregowego jest stosunkowo powolny, a nawet gdy zdarza się zdarzenie szeregowe, czas się kończy i zostaje zgłoszony TimeoutException
. Co mogę zrobić, aby zatrzymać zegar przekroczenia limitu czasu w mojej przyszłości, gdy wydarzy się zdarzenie seryjne?
próbowałem go z AtomicReference
ale to niczego nie zmienia:
public class CommunicationTask implements Callable<Response>, Observer {
private AtomicReference atomicResponse = new AtomicReference(new Response("timeout"));
private CountDownLatch latch = new CountDownLatch(1);
private SerialPort port;
CommunicationTask(SerialCommunicator communicator, Request request) {
this.communicator = communicator;
this.message = request.serialize();
this.port = communicator.getPort();
}
@Override
public Response call() throws Exception {
return query(message);
}
public Response query(String message) {
communicator.getListener().addObserver(this);
message = message + "\r\n";
try {
port.writeString(message);
} catch (Exception e) {
log.warn("Could not write to port: " + e);
communicator.disconnect();
}
try {
latch.await();
} catch (InterruptedException e) {
log.info("Execution time out.");
}
communicator.getListener().deleteObserver(this);
return (Response)atomicResponse.get();
}
@Override
public void update(Observable o, Object arg) {
atomicResponse.set((Response)arg);
latch.countDown();
}
}
Co mogę zrobić, aby rozwiązać ten problem?
EDYTOWANIE:
Ok Miałem jeden błąd. Odliczałem zatrzask przed ustawieniem atomicResponse
w mojej funkcji update
. Teraz wydaje się działać, ale wciąż pozostaje pytanie, czy to podejście jest właściwą drogą?
można dodać 'metody isCommunicationStarted' do listy CommunicationTask - kiedy wychwycisz 'TimeoutException', sprawdź' isCommunicationStarted' - jeśli zwróci false => cancel, w przeciwnym razie spróbuj ponownie 'future.get()' (być może z nowym czasem oczekiwania). – assylias
Czy podzielisz swoją klasę zadań na dwie: najpierw zaczekasz, aż wydarzenie rozpocznie się z przekroczeniem limitu czasu, a na początku zdarzenia zada zadanie drugiego typu. 2. zadanie odpowiednio przetworzy wydarzenie. –
Nie jest całkiem jasne, co chcesz osiągnąć. Ustawienie limitu czasu oznacza, że zdarzenia, które dotarły po przekroczeniu limitu czasu, mogą zostać zignorowane. Jeśli tak, to dlaczego rozpatrywany przypadek narożny ma znaczenie? – axtavt