2015-12-10 14 views
8

Il programma termina dopo nove stampe:Come fermare un ScheduledExecutorService?

class BeeperControl { 

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 

    public void beep() { 
     final Runnable beeper = new Runnable() { 
      public void run() { 
       System.out.println("beep"); 
      } 
     }; 
     final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
       beeper, 1, 1, SECONDS); 
     scheduler.schedule(new Runnable() { 
      public void run() { 
       beeperHandle.cancel(true); 
      } 
     }, 1 * 9, SECONDS); 
    } 

    public static void main(String[] args) { 
     BeeperControl bc = new BeeperControl(); 
     bc.beep(); 
    } 
} 

Come fermare un processo (cioè processo java in Eclipse per esempio), perché non si ferma dopo un limite di tempo in 9 secondi?

+0

Beh ... Cosa intendi con "non si ferma dopo un limite di tempo in 9 secondi"? L'ho appena testato e il "beep" si ferma dopo 9 secondi, come previsto. L'intero programma non si ferma, ovviamente, perché non hai chiuso il pool di thread. Se - invece di annullare il cicalino - è sufficiente spegnere il programmatore dopo 9 secondi, il programma uscirà normalmente. È questo il comportamento che volevi? – Seelenvirtuose

risposta

11

Il problema che si verifica è che lo scheduler mantiene un thread attivo dopo aver annullato il task beep.

Se è presente un thread non daemon attivo, la JVM rimane attiva.

Il motivo che mantiene questa discussione intorno è che avete detto di farlo in questa linea:

private final ScheduledExecutorService scheduler 
     = Executors.newScheduledThreadPool(1); 

nota la documentazione di newScheduledThreadPool(int corePoolSize):

corePoolSize - il numero di thread tenere in piscina, anche se sono inattivo.

Quindi, avete due possibili modi per causare la JVM per terminare:

  1. Passo 0 a newScheduledThreadPool invece di 1. Lo scheduler non manterrà un filo dal vivo, e la JVM terminerà.

  2. Arresta il programma di pianificazione. Dovresti farlo comunque per liberare le sue risorse. Quindi cambiare il run nel vostro anonimo Runnable a:

    public void run() { 
        beeperHandle.cancel(true); 
        scheduler.shutdown(); 
    } 
    

(In realtà, non è necessario il cancel lì - il shutdown entrerà in vigore al più presto il prossimo "beep" è completata.)

+0

Avete notato problemi in cui un thread sta eseguendo il vecchio codice e non può essere arrestato anche dopo che il server è stato riavviato e apache e tomcat sono stati chiusi e riservati. Ho una mail eseguibile che sta inviando alla tempistica sbagliata e ho cambiato il contenuto dell'email e la tempistica e ora sono state inviate 2 e-mail nonostante il mio codice (il mio codice su contextIntialized crea solo una eseguibile, quindi sospetto in qualche modo il vecchio runnable non è stato ucciso correttamente, perché ho dimenticato di aggiungere un codice di arresto nella vecchia versione del codice) Il tuo consiglio sarebbe utile: D –