2013-12-11 13 views
16

ho il seguente codice:Java Thread.stop() vs Thread.interrupt()

renderThread = new Thread(new Runnable() { 

    @Override 
    public void run() { 
     for (int i = 0; i < 10000000; i++) { 
      System.out.println("Number: " + i); 
     } 
    } 
}); 

renderThread.start(); 

try { 
    Thread.sleep(100); 
} catch (InterruptedException ex) { 
    ex.printStackTrace(); 
} 

renderThread.interrupt(); //It should stop, but it does not stop. 

renderThread.interrupt() non interrompe il filo, si continua a correre. Se sostituisco renderThread.interrupt() con .stop(), il thread si arresta. Tuttavia, .stop() è deprecato. Quindi, qual è il modo corretto di fermare un thread, se stop è deprecato e interrupt non funziona?

+2

Perché pensi che chiamare "interrupt" dovrebbe _stop_ il thread? –

+1

possibile duplicato di [Come arrestare correttamente la discussione in Java] (http://stackoverflow.com/questions/10961714/how-to-properly-stop-the-thread-in-java) –

+3

@SotiriosDelimanolis Perché, colloquialmente, "interrompere qualcosa" e "fermare qualcosa" sono sinonimi .. Non dico che è ciò che fa * (e la documentazione è un buon punto di partenza per srotolare l'assunto), ma il nome è caricato. – user2864740

risposta

18

Quando si chiama interrupt(), si attiva un flag booleano che indica alla funzione di esecuzione che deve essere interrotta. Questo è il motivo per cui di solito scrivo le mie funzioni di esecuzione in questo modo.

void run() 
{ 
    while(!Thread.interrupted()) 
    { 
     //Do something 
    } 
} 

Solo perché si chiama interruzione non significa che il thread si fermerà immediatamente o del tutto. Dipende da cosa è nella funzione di corsa.

+0

Quindi significa che dopo che si è verificato un evento di interruzione e il codice raggiunge la fine di 'run()', il thread cessa automaticamente di esistere? –

+1

Sì. Per quanto ne so, i thread dovrebbero fermarsi solo quando si esce dalle uscite. Interrompere la corsa fa solo sapere che dovrebbe uscire il prima possibile. Il problema con la chiamata stop() è che dire run() ha dovuto fare un po 'di pulizia come chiudere un flusso quindi questo non accadrebbe. – chasep255

+1

Penso che questa soluzione non possa risolvere la domanda qui. Quando renderThread esegue l'attività, non ha alcuna possibilità di verificare Thread.interrupted(). – Jimmy

6

Per spingere davvero il punto perché non dovresti usare Thread.stop()?

Doug Lea ha recentemente detto che Thread.stop sarà il primo metodo de attuate per Java venire Java 8.

La sua risposta a questo commento da qualcuno:

Inoltre, un'altra cosa sincronizzata sta andando per esso è che gestisce interruzioni asincrone di thread (Ie thread.stop()). So che stop() è deprecato e tutto, ma non si sa mai.

Was:

Ma ti conosco! A partire da JDK8, Thread.stop è davvero sparito. È il primo metodo deprecato di che è stato effettivamente de-implementato. Ora lancia semplicemente UnsupportedOperationException.

http://cs.oswego.edu/pipermail/concurrency-interest/2013-December/012028.html

+5

Eppure Java 8 è qui e così è Thread.stop ... LOL. –

1

renderThread.interrupt() non interrompe il filo, si continua correre.

  • Se il thread sta eseguendo e interrupt() viene richiamato è stato di interrupt è impostato.
  • Se questa discussione è bloccato in un'invocazione uno dei wait metodi della classe Object, o dei Thread.join e Thread.sleep metodi di questa classe quindi allo stato interrupt vengono annullati e riceverà un InterruptedException.

Ad esempio:

Thread t = new Thread() 
     { 
      public void run() 
      { 
       try { 
        for(int i=0; i<10000;i++) 
         System.out.println("Is interrupTed? "+this.isInterrupted()); 

        Thread.sleep(200); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
       } 

      } 
     }; 
     t.start(); 
     t.interrupt(); 
    } 

Il codice sopra, ho usato un ciclo for per intercettare la bandiera interrput con isInterrupted() funzione e stampato esso. Se viene invocato t.interrupt(), isInterrupted() restituirà true che verrà visualizzato nella console. Non appena raggiunge lo Thread.sleep(miliTime) vedrai che è stato catturato lo InterruptedException che è stato lanciato come descritto sopra.

Arresto del filo:

si potrebbe fare uso di questo controllo isInterrupted() flag se un interrupt() stato richiamato su di esso e restituire dall'esecuzione:

Ad esempio:

Thread t = new Thread() 
     { 
      public void run() 
      { 
       long executeTime = System.currentTimeMillis() ; 
       int i = 0;  
       for(; i<10000 && !this.isInterrupted();i++) 
         System.out.println("Is interrupted? "+this.isInterrupted()); 

       System.out.println("Was Interrupted? "+this.isInterrupted() 
            +" after cycle: "+ i); 
       System.out.println("Time it gets Executed: " 
            +(System.currentTimeMillis() - executeTime+" ms")); 

      } 
     }; 
     t.start(); 
     try { 
      Thread.sleep(200); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 
     t.interrupt(); 

Durante l'esecuzione del codice precedente: ho inviato il thread principale in modalità sospensione per 200 all'interno dello statico funzione principale per consentire al thread avviato t di funzionare per un po 'di tempo. Poi Invocai
t.interrupt() su esso pertanto il ciclo for di fermarsi e stampare un'uscita come segue:

Was Interrupted? true after cycle: 1477 
Time it gets Executed: 258 ms 

che indica che il ciclo for ha 1148 iterazione prima t.interrupt(); stato richiamato nella funzione main.

Leggere la documentazione della funzione Thread.interrupt() per ulteriori dettagli.

3

Tutto quello che dovete fare per interrompere il thread corrente o terminare il processo in esecuzione del filo è quello di aggiungere l'istruzione di seguito all'interno si cattura blocco

try 
{ 
    Thread.sleep(4000); 
    System.out.println("VAS CONSULTING") 
} 
catch(InterruptedException e) 
{ 
    //Stop printing out VAS CONSULTING 
    return; /*This will terminate the thread*/ 
} 

anche se un metodo che non buttare un Interrupted eccezione non viene utilizzato entro il metodo run si può fare questo per trattare filetto di interruzione o terminare la discussione

@Override 
public void run() 
{ 

    System.out.println("VAS CONSULTING"); 
    if(Thread.Interrupted()) 
    { 
    doSomethingElse();//process something else within the thread 
    return; //Terminates the current Thread 
    } 

} 

Spero che questo tu o qualcun altro aiuta.