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.
- 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
ThreadDeath
Thread#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. - 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 unInterruptedException
. - 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.
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