Java Language différences de gestion des exceptions submit () vs execute ()


Exemple

Généralement, la commande execute () est utilisée pour les appels d'incendie et d'oubli (sans analyse du résultat) et la commande submit () est utilisée pour analyser le résultat d'un objet Future.

Nous devons être conscients de la différence clé entre les mécanismes de gestion des exceptions entre ces deux commandes.

Les exceptions de submit () sont avalées par framework si vous ne les avez pas capturées.

Exemple de code pour comprendre la différence:

Cas 1: soumettez la commande Runnable with execute (), qui signale l’exception.

import java.util.concurrent.*;
import java.util.*;

public class ExecuteSubmitDemo {
    public ExecuteSubmitDemo() {
        System.out.println("creating service");
        ExecutorService service = Executors.newFixedThreadPool(2);
        //ExtendedExecutor service = new ExtendedExecutor();
        for (int i = 0; i < 2; i++){
            service.execute(new Runnable(){
                 public void run(){
                    int a = 4, b = 0;
                    System.out.println("a and b=" + a + ":" + b);
                    System.out.println("a/b:" + (a / b));
                    System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
                 }
            });
        }
        service.shutdown();
    }
    public static void main(String args[]){
        ExecuteSubmitDemo demo = new ExecuteSubmitDemo();
    }
}

class ExtendedExecutor extends ThreadPoolExecutor {

   public ExtendedExecutor() { 
       super(1, 1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
   }
   // ...
   protected void afterExecute(Runnable r, Throwable t) {
     super.afterExecute(r, t);
     if (t == null && r instanceof Future<?>) {
       try {
         Object result = ((Future<?>) r).get();
       } catch (CancellationException ce) {
           t = ce;
       } catch (ExecutionException ee) {
           t = ee.getCause();
       } catch (InterruptedException ie) {
           Thread.currentThread().interrupt(); // ignore/reset
       }
     }
     if (t != null)
       System.out.println(t);
   }
 }

sortie:

creating service
a and b=4:0
a and b=4:0
Exception in thread "pool-1-thread-1" Exception in thread "pool-1-thread-2" java.lang.ArithmeticException: / by zero
        at ExecuteSubmitDemo$1.run(ExecuteSubmitDemo.java:15)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
java.lang.ArithmeticException: / by zero
        at ExecuteSubmitDemo$1.run(ExecuteSubmitDemo.java:15)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)

Cas 2: Remplacez execute () par submit (): service.submit(new Runnable(){ Dans ce cas, les exceptions sont englouties par framework car la méthode run () ne les a pas capturées explicitement.

sortie:

creating service
a and b=4:0
a and b=4:0

Cas 3: Modifiez le newFixedThreadPool en ExtendedExecutor

//ExecutorService service = Executors.newFixedThreadPool(2);
 ExtendedExecutor service = new ExtendedExecutor(); 

sortie:

creating service
a and b=4:0
java.lang.ArithmeticException: / by zero
a and b=4:0
java.lang.ArithmeticException: / by zero

J'ai montré cet exemple pour couvrir deux sujets: Utilisez votre ThreadPoolExecutor personnalisé et gérez Exectpion avec ThreadPoolExecutor personnalisé.

Autre solution simple au problème ci-dessus: Lorsque vous utilisez la commande normale ExecutorService & submit, obtenez l'objet Future de la commande submit (), appelez get () API sur Future. Catch les trois exceptions, qui ont été citées dans l'implémentation de la méthode afterExecute. Avantage de ThreadPoolExecutor personnalisé par rapport à cette approche: vous devez gérer le mécanisme de gestion des exceptions dans un seul endroit - Custom ThreadPoolExecutor.