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)
È stato utile?

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().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top