2015-11-15 14 views
6

Questa non è una domanda su come terminare in modo pulito un thread, ovvero chiamando l'interrupt su di esso e facendo in modo che il thread risponda in modo appropriato. Non riesco a modificare il codice che il thread sta eseguendo in alcun modo.Come posso terminare immediatamente una discussione? (Non interrotto)

Voglio in particolare terminare immediatamente un thread, non mi interessa affatto lo stato in cui sono lasciate le cose. So che qualcosa di simile è possibile usando Thread.stop, tuttavia questo in effetti genera un'eccezione di ThreadDeath, e per il Thread per terminare questa eccezione non può essere catturato. Tuttavia, il codice di cui sto trattando cattura questa eccezione e non la sta rilanciando.

Thread.destroy() sembrava essere quello che stavo cercando, tuttavia questo metodo non è mai stato implementato. C'è un altro modo per raggiungere questo?

+0

Si interrompe e interromperà l'esecuzione e verrà eseguito nel ciclo successivo. Qual'è il problema? – texasbruce

+1

Non interrompe semplicemente imposta il flag di interrupt o genera un'eccezione? (Che sono presi nel codice con cui ho a che fare) Il thread non smette mai di essere eseguito, ha solo un flag set. – tixopi

risposta

3

Credo che in Java non sia possibile uccidere un thread come si descrive. Come si nota in un commento, interrupt non farà ciò che si desidera. Se il thread è in esecuzione, imposta semplicemente un flag e tocca al thread per notarlo. se il thread è in attesa o sta dormendo, genererà un valore InterruptedException.

L'unico modo che posso immaginare di fare quello che stai descrivendo è quello di uccidere il processo in cui il thread è in esecuzione. (Ad esempio, chiamare System.exit(int).)

+0

Grazie. Non è la risposta che speravo, ma quella che mi aspettavo. – tixopi

0

Se siete su Java 7 o versioni precedenti, è possibile utilizzare il stop(Throwable obj) metodo di overload di gettare qualcosa oltre un errore di ThreadDeath:

Forces the thread to stop executing. If the argument obj is null , a NullPointerException is thrown (in the current thread). The thread represented by this thread is forced to stop whatever it is doing abnormally and to throw the Throwable object obj as an exception. This is an unusual action to take; normally, the stop method that takes no arguments should be used.

Questo metodo, come la versione senza parametri, è deprecato, quindi tienilo a mente.

+2

È interessante notare che il metodo 'stop (Throwable obj)' in Java 8 genererà sempre un 'UnsupportedOperationException' e non ucciderà il thread. – terminex9

2

No, non c'è un modo. Da Java Concurrency in Practice:

Since there is no preemptive way to stop a thread, they must instead be persuaded to shut down on their own.

Interruzione di un filo non è il modo più pulito come hai detto. modi puliti potrebbero essere:

  1. ExecutorService.shutdown()
  2. Future.cancel()
  3. veleno pillole

Non sono destinati a presentare le attività di threads che richiedere molto tempo per essere fatto. Preferiresti dividerli in compiti più piccoli e inviare un poison pill per annullare l'attività più grande. Se non c'è un modo per farlo, quindi process a e ucciderlo se si desidera annullare l'attività.

1

Se non ti fidi del thread in questione al punto che devi ucciderlo, probabilmente dovresti eseguirlo in un processo separato e uccidere invece il processo.

In ogni caso, il codice seguente potrebbe funzionare se siete ok con le deprecate Thread metodi:

while (theThread.isAlive()) { 
     theThread.stop(); 
    } 

seconda quanto male il thread sta cercando di sopravvivere ...

si potrebbe desiderare di eseguire questo codice in più thread o ripetere la chiamata stop() se questo non è sufficiente.Tuttavia, sono riuscito a eliminare la seguente discussione con questo codice:

final Thread iWontDie = new Thread(() -> { 
     int i = 0; 
     while (true) { 
      try { 
       System.out.println("I'm still alive! " + ++i); 
      } catch (Throwable t) { 
       // eat t 
      } 
     } 
    }); 
    iWontDie.start(); 
+1

Questa tecnica non funzionerà sempre. Dalla [Documentazione Java SE sui metodi 'Thread' deprecati] (http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html): _" Va notato che in tutto situazioni in cui un thread in attesa non risponde a 'Thread.interrupt', _it non risponde a_' Thread.stop' _either._ Tali casi includono attacchi di denial-of-service deliberati e operazioni di I/O per quale thread. stop e thread.interrupt non funzionano correttamente. " –

+0

Mi piace questa risposta, e funziona per l'esempio che ho menzionato nella domanda su come catturare ThreadDeath, perché stop viene chiamato quando si trova nel blocco catch a quel punto l'errore ThreadDeath viene nuovamente generato e può ora propagarsi correttamente. Tuttavia, come menziona Ted Hopp, questo non sempre funziona, in particolare se un thread è (bloccato) cercando di ottenere un monitor, non risponderà per fermarsi. Comunque, mi piace il tuo modo di pensare, lo spammare con arresti finché non muore. – tixopi

Problemi correlati