Nessuna uscita da Exception
-
20-09-2019 - |
Domanda
Perché questo codice non stampare una traccia dello stack eccezione?
public class Playground {
/**
* @param args
*/
public static void main(String[] args) {
startThread();
}
private static void startThread() {
ScheduledExecutorService timer = Executors
.newSingleThreadScheduledExecutor();
Runnable r = new Runnable() {
int dummyInt = 0;
boolean dummyBoolean = false;
@Override
public void run() {
dummyInt = Integer.parseInt("AAAA");
if (dummyBoolean) {
dummyBoolean= false;
} else {
dummyBoolean= true;
}
}
};
timer.scheduleAtFixedRate(r, 0, 100, TimeUnit.MILLISECONDS);
}
}
Come posso farlo?
mi sarei aspettato di vedere questo:
java.lang.NumberFormatException: For input string: "AAAA"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Playground$1.run(Playground.java:25)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Soluzione
L'esecutore probabilmente imposta il proprio gestore eccezioni non rilevate sul filo, quindi l'analisi dello stack non sarà stampato sulla console. Se viene generata un'eccezione nel Runnable
si può ottenere dall'oggetto ScheduledFuture
restituito dal metodo scheduleAtFixedRate
:
ScheduledFuture<?> future = timer.scheduleAtFixedRate(r, 0, 100, TimeUnit.MILLISECONDS);
try {
future.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
cause.printStackTrace();
}
Altri suggerimenti
Il servizio esecutore tende a ingoiare eccezioni per qualche ragione. Si può fare il debug molto impegnativo. Basta aggiungere un tentativo di cattura in tutto il contenuto del metodo di esecuzione in questo modo:
public void run() {
try
dummyInt = Integer.parseInt("AAAA");
if (dummyBoolean) {
dummyBoolean= false;
} else {
dummyBoolean= true;
}
} catch (Exception e){
e.printStackTrace();
}
}
Ecco una questione connessa.
C'è una domanda simile che fornisce una risposta con Java esecutori in programma qui su StackOverflow.
In sostanza quello che si può leggere nel scheduleAtFixedRate () javadoc :
Se uno qualsiasi esecuzione del compito incontra un'eccezione, successiva le esecuzioni vengono soppressi
Quindi, mi piacerebbe generalizzare da qui che non si arriva a vedere le vostre eccezioni al momento della presentazione compiti attraverso ScheduledExecutorService.scheduleAtFixedRate()
.