2013-09-05 26 views
5

Sto lavorando a un'applicazione che a un certo punto avvia un thread di lavoro. Il comportamento di questa discussione può variare notevolmente a seconda dei parametri utilizzati per avviarlo, ma il seguente elenco di proprietà si applicano:Come gestire correttamente gli interrupt di thread

  • farà alcuni mi minore/operazioni O
  • la spesa sarà di minor tempo nelle biblioteche 3rd party
  • può creare qualche thread di lavoro per un certo compito parziale (questi fili non saranno riutilizzati dopo il loro compito è finito)
  • che spenderà più dei suoi numeri di tempo scricchiolio (non ci sono chiamate di blocco presente)

A causa della possibile lunga durata (da 5 minuti a diverse ore, a seconda dell'ingresso), vogliamo essere in grado di interrompere il calcolo. Se scegliamo di abortire, non ci interessa più l'output, e il thread sta sprecando risorse preziose finché continua a funzionare. Poiché il codice è sotto il nostro controllo, the advised way utilizza interrupt per indicare l'interruzione.

Mentre la maggior parte degli esempi sul Web si occupano di un thread di lavoro che scorre su un metodo, questo non è il mio caso (similar question here). Ci sono anche pochissime chiamate di blocco in questo thread di lavoro, nel qual caso this article consiglia di controllare manualmente il flag di interrupt. La mia domanda è: Come gestire questo interrupt?

Vedo diverse opzioni, ma non riesco a decidere quale sia l'approccio più "pulito". Nonostante il mio esempio pratico, sono principalmente interessato alle "migliori pratiche" su come affrontarlo.

  1. gettare un po 'tipo di eccezioni non controllata: questo avrebbe ucciso il filo in modo semplice e veloce, ma mi ricorda l'approccio utilizzato dal ThreadDeathThread#stop() metodo deprecato, con tutta la sua related problems. Riesco a vedere questo approccio accettabile nel codice di proprietà (a causa del flusso logico noto), ma non nel codice della libreria.
  2. Lancia un qualche tipo di eccezione controllata: questo ucciderebbe il thread in modo semplice e rapido e allevia i problemi di tipo ThreadDeath imponendo ai programmatori di gestire questo evento. Tuttavia, pone un grande onere sul codice, richiedendo l'eccezione da menzionare ovunque. C'è una ragione per cui non tutto getta un InterruptedException.
  3. Uscire dai metodi con un "risultato migliore finora" o risultato vuoto. A causa della quantità di classi coinvolte, questo sarà un compito molto difficile. Se non si presta sufficiente attenzione, è possibile che NullPointerExceptions provenga da risultati vuoti, causando gli stessi problemi del punto 1. Trovare queste cause sarebbe quasi impossibile in basi di codice di grandi dimensioni.
+0

Probabilmente si potrebbe provare a semplificare (3) nel gestore o gestore di interrupt; ancora, potrebbe essere una buona idea considerando una combinazione di questo con una sorta di RuntimeException. – blgt

risposta

1

Vi suggerisco di controllare Thread.currentThread(). IsInterrupted() periodicamente in punti si knwo è sicuro di fermarsi e fermare se è impostato.

È possibile eseguire questa operazione in un metodo che controlla questo flag e genera un'eccezione o un errore non controllato personalizzato.

+0

Conoscete solo i punti sicuri per l'arresto se tutto il codice in esecuzione è sotto il vostro controllo. Come gestiresti questo se il codice è destinato a una biblioteca? (Vedere il punto 1 nella mia domanda) – DieterDP

0

Che dire di un utilizzo di ExecutorService per eseguire il Runnable? Scopri i metodi in cui puoi specificare il timeout. Per esempio.

ExecutorService executor = Executors.newSingleThreadExecutor(); 
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes. 
executor.shutdown(); 

Qui Task ovviamente implementa Runnable.

+0

Questa risposta mi dice come posso creare interrupt nel mio thread di lavoro, ma non come dovrei gestirli - che è la mia domanda reale. – DieterDP

Problemi correlati