Maison > Java > javaDidacticiel > Comment résoudre le problème de la haute concurrence InterruptedException en Java

Comment résoudre le problème de la haute concurrence InterruptedException en Java

WBOY
Libérer: 2023-04-30 08:46:06
avant
1691 Les gens l'ont consulté

Avant-propos

InterruptedException n'est peut-être pas aussi simple que vous le pensez !

Lorsque nous appelons la méthode wait() d'un objet Java ou la méthode sleep() d'un thread, nous devons intercepter et gérer l'exception InterruptedException. Si nous gérons incorrectement InterruptedException, des conséquences inattendues se produiront !

Cas du programme

Par exemple, dans le code de programme suivant, la classe InterruptedTask implémente l'interface Runnable. Dans la méthode run(), le handle du thread actuel est obtenu, et dans la boucle while(true), le courant. le thread est détecté via la méthode isInterrupted(). Si le thread est interrompu, si le thread actuel est interrompu, quittez la boucle while(true). En même temps, dans la boucle while(true), il y a aussi une ligne de. Thread.sleep(100) et l’exception InterruptedException est capturée.

Le code complet est affiché ci-dessous.

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 线程测试中断
 */
public class InterruptedTask implements Runnable{
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        while (true){
            if(currentThread.isInterrupted()){
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
Copier après la connexion

L'intention initiale du code ci-dessus est de vérifier si le thread a été interrompu via la méthode isInterrupted() et de quitter la boucle while si elle est interrompue. D'autres threads interrompent le thread d'exécution en appelant la méthode interruption() du thread d'exécution. À ce moment, le bit d'indicateur d'interruption du thread d'exécution est défini, de sorte que currentThread.isInterrupted() renvoie true, afin que la boucle while puisse être. sorti.

Cela ne semble poser aucun problème ! Mais est-ce vraiment le cas ? Nous créons une classe InterruptedTest pour les tests, le code est le suivant.

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 测试线程中断
 */
public class InterruptedTest {
    public static void main(String[] args){
        InterruptedTask interruptedTask = new InterruptedTask();
        Thread interruptedThread = new Thread(interruptedTask);
        interruptedThread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        interruptedThread.interrupt();
    }
}
Copier après la connexion

Nous exécutons la méthode principale comme indiqué ci-dessous.

Comment résoudre le problème de la haute concurrence InterruptedException en Java

Analyse du problème

Le code ci-dessus appelle clairement la méthode interruption() du thread pour interrompre le thread, mais cela n'a aucun effet. La raison en est que lorsque la méthode run() du thread est exécutée, elle est bloquée la plupart du temps lors de sleep(100). Lorsque d'autres threads interrompent le thread d'exécution en appelant la méthode interruption() du thread d'exécution, InterruptedException sera déclenchée avec un. Forte probabilité. Exception, lorsque l'exception InterruptedException est déclenchée, la JVM effacera le bit d'indicateur d'interruption du thread en même temps, donc le currentThread.isInterrupted() jugé dans la méthode run() à ce moment retournera false, et la boucle while actuelle ne se terminera pas.

Maintenant que l'analyse du problème a été résolue, comment interrompre le fil de discussion et quitter le programme ?

Problème résolu

La bonne façon de le résoudre devrait être d'intercepter l'exception dans la boucle while(true) de la méthode run() dans la classe InterruptedTask, puis de réinitialiser le bit de l'indicateur d'interruption, de sorte que le code correct de la classe InterruptedTask Comme indiqué ci-dessous.

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 中断线程测试
 */
public class InterruptedTask implements Runnable{
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        while (true){
            if(currentThread.isInterrupted()){
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
                currentThread.interrupt();
            }
        }
    }
}
Copier après la connexion

Comme vous pouvez le voir, nous avons ajouté une nouvelle ligne de code dans le bloc de code catch qui capture l'exception InterruptedException.

currentThread.interrupt();
Copier après la connexion

Cela nous permet de après avoir détecté l'exception InterruptedException, nous pouvons réinitialiser le bit d'indicateur d'interruption du thread, interrompant ainsi le thread en cours d'exécution.

Nous exécutons à nouveau la méthode principale de la classe InterruptedTest comme indiqué ci-dessous.

Comment résoudre le problème de la haute concurrence InterruptedException en Java

Résumé

Soyez prudent lors de la gestion d'InterruptedException. Si une InterruptedException est levée lors de l'appel de la méthode interrompue () du thread d'exécution pour interrompre le thread d'exécution, alors lorsque l'exception InterruptedException est déclenchée, la JVM interrompra simultanément le thread d'exécution. Le bit de l'indicateur d'interruption est effacé à ce moment-là, lorsque la méthode isInterrupted() du thread d'exécution est appelée, false sera renvoyé.

À l'heure actuelle, la bonne façon de le gérer est d'intercepter l'exception InterruptedException dans la méthode run() du thread d'exécution et de réinitialiser le bit de l'indicateur d'interruption (c'est-à-dire dans le bloc de code catch qui intercepte l'exception InterruptedException, re -appelez la méthode interruption() du thread actuel.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal