2011-01-13 14 views
6

La mia domanda è leggermente complicata. Lascia che provi a spiegarlo a fondo, ma se hai bisogno di maggiori dettagli, sentiti libero di chiedermelo, li aggiungerò.Come viene ucciso un threadPoolExecutor con i thread "Occupati"?

Ho appreso di recente (tramite esperimento) che se un thread esegue continuamente il lavoro, qualcosa come un'operazione intera in un ciclo while (vero), l'interruzione del thread non ha alcun effetto su di esso. La discussione continua come se nulla fosse accaduto.

Ora, ThreadPoolExecutors viene ucciso utilizzando i metodi shutDown() o shutDownNow(). Ho controllato il codice per questi metodi, usano la chiamata interrupt() per uccidere un thread. Quindi, se tutti i thread sono impegnati a fare cose, come si ucciderà un esecutore? Come viene ucciso, ad esempio quando lo utilizziamo nelle app di primavera.

Una tale esecutore sarà simile:

import java.io.File; 
import java.io.IOException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Test { 
    public static void main(String[] a) { 
     ExecutorService ex = Executors.newFixedThreadPool(50); 
     for (int i = 0; i < 50; i++) { 
      ex.execute(new Thread() { 
       public void run() { 
        try { 
         File f = File.createTempFile("testfile", "txt"); 
         while (true) { 
          f.canRead(); 
         } 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } finally { 
        } 
       } 
      }); 
     } 

     ex.shutdown(); 
     ex.shutdownNow(); 
    } 
} 

risposta

5

Per rispondere alla tua domanda principale, non sarebbe, non meno che la JVM è stato detto esplicitamente di uscita via System.exit().

Per le operazioni di lunga durata che devono essere interrompibili, è responsabilità dell'implementazione controllare il flag di interrupt tramite Thread.currentThread().isInterrupted().

Ad esempio:

import java.io.File; 
import java.io.IOException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Test { 
    public static void main(String[] a) { 
     ExecutorService ex = Executors.newFixedThreadPool(50); 
     for (int i = 0; i < 50; i++) { 
      ex.execute(new Runnable() { 
       public void run() { 
        try { 
         File f = File.createTempFile("testfile", "txt"); 
         while (!Thread.currentThread().isInterrupted()) { 
          f.canRead(); 
         } 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } finally { 
        } 
       } 
      }); 
     } 

     ex.shutdown(); 
     ex.shutdownNow(); 
    } 
} 

noti inoltre che non è adatto per creare un'istanza di Thread destinate esclusivamente come Runnable. In questo modo si crea una sorta di indirezione che potrebbe confondere i programmatori più ingenui.

+0

ohh, non ne ero consapevole. Perdonami per la mia ignoranza. Credo che dovrei leggere un libro di base, forse, Concurrency in pratica. Grazie! – cheekoo

+1

@cheekoo, Java Concurrency in Practice è un libro altamente raccomandato. Effective Java di Joshua Bloch è un'altra buona scelta per una copertura materiale un po 'più ampia. –

0

Non si dovrebbe essere avere un ciclo infinate nel codice.

Il pool di thread non attende l'uscita dei thread.

Il filo durerà per sempre fino a quando la JVM esce

+0

Sono d'accordo, questa non è una discussione ideale, ma vuoi dire che una discussione come questa non può essere uccisa in alcun modo? – cheekoo

+0

@cheekoo il ** pool ** verrà ucciso, ma questi thread non lo faranno. –

+0

Grazie TSM per la tua risposta. Questo è interessante, non ho mai saputo che un pool di thread può essere ucciso mentre i thread che sta gestendo sono ancora in esecuzione. Cercherò di eseguire il debug di questo. Avevo l'impressione che i fili rimanessero vivi, così come la piscina. – cheekoo

Problemi correlati