Maison >Java >javaDidacticiel >Explication détaillée des exemples Java : exception de tâche de sous-thread, restauration de la transaction du thread principal

Explication détaillée des exemples Java : exception de tâche de sous-thread, restauration de la transaction du thread principal

WBOY
WBOYavant
2022-05-09 17:49:493531parcourir

Cet article vous apporte des connaissances pertinentes sur java, qui présente principalement des problèmes liés à la façon d'annuler la transaction du thread principal lorsqu'une exception se produit dans la tâche de sous-thread, y compris la capture d'exception et l'annulation de transaction, etc. Jetons un coup d'œil au contenu ci-dessous, j’espère que cela sera utile à tout le monde.

Explication détaillée des exemples Java : exception de tâche de sous-thread, restauration de la transaction du thread principal

Étude recommandée : "Tutoriel vidéo Java"

1. Posez une question

Le thread principal a soumis une tâche au pool de threads. Si une exception se produit lors de l'exécution de cette tâche, comment. pour laisser le fil principal L'exception est interceptée et la transaction est annulée.

2. Fil principal et sous-fil

Jetons d'abord un coup d'œil aux bases. L'image ci-dessous montre comment fonctionnent les deux fils

  • L'image de gauche montre qu'après le fil principal, un. sous-fil, le second Ils fonctionnent indépendamment sans interférer les uns avec les autres. La vie et la mort sont déterminées par le destin, vous et moi ne sommes que des passants !
  • L'image de droite montre que le thread principal démarre un sous-thread, puis continue d'exécuter la logique du programme du thread principal et obtient le résultat de l'exécution du sous-thread en bloquant à un certain nœud.

Explication détaillée des exemples Java : exception de tâche de sous-thread, restauration de la transaction du thread principal

Pour le problème soulevé ci-dessus, la deuxième méthode doit consister à résoudre le problème selon lequel le thread principal peut capturer les exceptions qui se produisent lors de l'exécution du thread enfant. Je dois poser une question d'entretien ici, la différence entre les deux interfaces Callable et Runnable qui implémentent les threads :

public interface Callable<v> {
    V call() throws Exception;}</v>
public interface Runnable {
    public abstract void run();}

Vous pouvez voir que la méthode call a une valeur de retour et que la méthode run n'a pas de valeur de retour. De plus, la méthode call peut lever des exceptions, mais pas la méthode run. Évidemment, afin de capturer ou de connaître les résultats d'exécution des sous-threads ou d'exécuter des exceptions, nous devons l'implémenter via l'interface Callable.

Ici, nous écrivons une classe ExpSubThread (classe de simulation d'exception de sous-thread), implémentons l'interface Callable et lançons directement une exception de pointeur nul sans faire trop d'actions.

public class ExpSubThread implements Callable {
    @Override
    public Object call() throws Exception {
        throw new NullPointerException();
    }}

3. Pool de threads

Lorsque nous sommes confrontés à des tâches de thread, nous établissons généralement un pool de threads à l'avance. Le pool de threads est une collection pré-planifiée de n ressources de thread. Son avantage est le suivant :

  • Lors de l'exécution d'une tâche, il ne crée pas de nouveau thread, mais utilise les ressources de thread existantes dans le pool de threads. Lorsque l'exécution de la tâche est terminée, la ressource de thread n'est pas détruite, mais la ressource de thread est renvoyée au pool de threads. Par conséquent, dans une certaine mesure, les ressources consommées par la création et la destruction des threads sont économisées et l'objectif de réutilisation des ressources des threads est atteint.
  • Étant donné qu'il existe une limite supérieure à la taille de la création du pool de threads, une autre fonction du pool de threads est d'éviter la création illimitée de threads et d'éviter les pannes du système causées par une occupation illimitée des ressources d'application.

Il existe deux pools de threads couramment utilisés, l'un est celui fourni avec le JDK et l'autre est le pool de threads Spring. Ce dernier est souvent utilisé dans l'environnement Spring, et ils sont similaires. Ici, nous utilisons l'API Spring pour créer un pool de threads.

public ThreadPoolTaskExecutor getThreadPool(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(100);  //线程池最大线程数
        executor.setCorePoolSize(50);//线程池核心线程数
        executor.setQueueCapacity(50);//任务队列的大小
        executor.setThreadNamePrefix("test_"); //线程前缀名
        executor.initialize(); //线程初始化
        return executor;}

4. Capture d'exception

Ce qui suit est un cas de test que j'ai écrit, où il représente le flux d'exécution du programme du thread principal

@Testvoid subThreadExceptionTest() {
        try{
            //新建子线程对象
            ExpSubThread expSubThread = new ExpSubThread();
            //构建线程池
            ThreadPoolTaskExecutor executor = getThreadPool();
            //提交子线程任务,submit方法
            Future future = executor.submit(expSubThread);
            //在这里可以做主线程的业务其他流程操作
            //阻塞等待子线程的执行结果
            Object obj = future.get();  
        }catch (Exception e){
            e.printStackTrace();
            //事务回滚
        }}

Ce qui doit être noté ici est d'utiliser la méthode submit pour soumettre des tâches de sous-thread. au pool de threads pour exécution. ThreadPoolTaskExecutor dispose de deux méthodes pour exécuter des tâches de thread, l'une est la méthode d'exécution et l'autre est la méthode de soumission.

  • La méthode d'exécution n'a pas de valeur de retour, il est donc impossible de juger si la tâche est terminée avec succès. La classe de thread correspondante implémente l'interface Runnable.
  • La méthode submit a une valeur de retour, renvoyant un Future, et la classe de thread correspondante implémente l'interface Callable.

Explication détaillée des exemples Java : exception de tâche de sous-thread, restauration de la transaction du thread principal

La méthode Future.get() atteint l'objectif de bloquer le thread principal, de sorte que le résultat de l'exécution de la tâche du sous-thread puisse être jugé et que la méthode get puisse lever une exception.

    V get() throws InterruptedException, ExecutionException;

L'image ci-dessous est l'effet du programme de cas de test ci-dessus e.printStackTrace(); Sur l'image, vous pouvez voir deux exceptions d'exception. L'une est l'exception de pointeur nul que nous lançons activement de manière simulée dans la tâche de sous-thread. l'autre Une ExecutionException levée par la méthode get en raison d'un pointeur nul.

Explication détaillée des exemples Java : exception de tâche de sous-thread, restauration de la transaction du thread principal

5. Annulation de transaction

Comme vous l'avez vu ci-dessus, nous avons implémenté l'interface Callable via la classe

  • thread pour atteindre l'objectif d'obtenir la valeur de retour du thread ou de lever une exception.
  • submit peut soumettre des tâches de thread au pool de threads et obtenir la valeur de retour Future du résultat de l'exécution du sous-thread.
  • La méthode get() de Future peut obtenir des informations sur l'exécution des sous-threads, y compris les exceptions levées.

Alors maintenant que nous pouvons détecter ou intercepter les informations d'exception du sous-thread dans le thread principal, est-il trop simple d'annuler la transaction du thread principal à l'étape suivante ?

  • jdbc implémente l'annulation des transactions via conn.rollback() conn.rollback()实现事务的回滚
  • spring环境下使用@Transactional
  • Utilisez simplement l'annotation @Transactional dans l'environnement Spring.

Apprentissage recommandé : "Tutoriel vidéo Java

"🎜

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer