2010-04-15 5 views
3

J'utilise un ThreadPool via ExecutorService. En appelant shutDownNow(), il interrompt tous les threads en cours d'exécution dans le pool. Quand cela arrive, je veux que ces threads abandonnent leurs ressources (connexions socket et db) et meurent simplement, mais sans continuer à exécuter de la logique, par exemple: en insérant quelque chose dans la BD. Quel est le moyen le plus simple d'y parvenir? Bellow est un exemple de code:Java: Autoriser le thread enfant à se tuer sur InterruptedException?

modifier: oublié de mentionner que toutes mes connexions sont libérées par finally. J'ai juste besoin de m'assurer que cela n'impliquera pas différentes insertions de DB d'une manière fiable.

public void threadTest() { 
    Thread t = new Thread(new Runnable() { 

      public void run() { 
       try { 
        Thread.sleep(999999); 
       } catch (InterruptedException e) { 
        //invoke thread suicide logic here 
       } 
      } 
     }); 
    t.start(); 

    t.interrupt(); 
    try { 
     Thread.sleep(4000); 
    } catch (InterruptedException e) { 
    } 
} 

Répondre

2

La forme canonique pour ce faire, à mon avis, implique jamais attraper le InterruptedException du tout.

De toute façon, vous devriez toujours libérer vos ressources dans un bloc finally, quel que soit le problème. Supposons que vous le soyez. Dans ce cas, tout ce que vous devez faire est de laisser la bulle InterruptedException atteindre le niveau supérieur (c'est-à-dire le déclarer dans la clause throws pour toutes vos méthodes) et voilà!

Certains peuvent hésiter à ajouter une exception vérifiée à toutes les méthodes. Cependant, ceci est conceptuellement correct - une méthode déclarée pour lancer InterruptedException signifie qu'il s'agit d'une méthode de blocage. Habituellement, seules les méthodes de bas niveau implémenteraient cela, car les méthodes de niveau supérieur impliquent rarement un blocage (c'est-à-dire que l'on pourrait proposer une alternative plausible/reporter à une autre dépendance qui ne l'exigerait pas). La chose vraiment douteuse est que vous voulez que votre code "s'arrête juste" comme ceci. Vous n'avez pas vraiment le contexte pour faire une telle chose inconditionnellement à partir d'un gestionnaire de thread, le code qui s'exécute dans les threads doit coopérer avec vos efforts. Donc laisser la bulle d'exception interrompue est une approche; un autre pourrait être d'attraper cette exception relativement bas et de définir un drapeau booléen stop que vous interrogez dans le code de niveau supérieur.

Dans tous les cas, la question ici est uniquement de savoir comment obtenir un code de plus haut niveau pour savoir qu'il devrait se terminer dans ce cas. Si vous fermez des ressources dans des blocs finally, comme vous le devriez, vous savez qu'ils seront toujours publiés de manière appropriée, indépendamment de toute autre chose.

+0

semble raisonnable, mais je Je devrais à peu près déclarer toutes les méthodes de mon projet comme 'throws InterruptedException', n'est-ce pas? – Zombies

+1

À moins que vous ne l'attrapiez à un niveau inférieur et que vous rejetiez à la place une exception non cochée. –

+0

Il est dommage que InterruptedException et RemoteException soient des exceptions vérifiées (à mon humble avis c'est-à-dire) –

0

Lorsque le thread termine sa méthode d'exécution, il meurt automatiquement. Donc, en effet, ne rien faire:

public void threadTest() { 
    Thread t = new Thread(new Runnable() { 

      public void run() { 
       try { 
        Thread.sleep(999999); 
       } catch (InterruptedException e) { 
        //invoke thread suicide logic here 
        // Do nothing so the thread will die 
       } 
      } 
     }); 
    t.start(); 

    t.interrupt(); 
    try { 
     Thread.sleep(4000); 
    } catch (InterruptedException e) { 
    } 
} 

Le fil sera libéré de la mémoire lorsque ThreadTest() se termine parce que la variable de fil ne sera plus référencé.

1

Veuillez noter qu'appeler t.interrupt() et laisser InterruptedException être levé n'aidera pas dans le cas d'un blocage ininterrompu (par exemple, pour les threads qui attendent que le moniteur soit libéré ou qui attendent une opération d'E/S).

Dans ces cas, vous devrez utiliser java.util.concurrent.locks.Lock explicite (qui est interruptible) au lieu de blocs synchronisés et java.nio au lieu de java.io

Questions connexes