123 votes

Exemple utile d'un crochet d'arrêt en Java ?

J'essaie de faire en sorte que mon application Java prenne des mesures raisonnables pour être robuste, et cela implique notamment une fermeture gracieuse. Je suis en train de lire crochets d'arrêt et je ne comprends pas vraiment comment les utiliser dans la pratique.

Existe-t-il un exemple concret ?

Imaginons que j'aie une application très simple comme celle ci-dessous, qui écrit des nombres dans un fichier, 10 par ligne, par lots de 100, et que je veuille m'assurer qu'un lot donné se termine si le programme est interrompu. Je sais comment enregistrer un crochet d'arrêt, mais je n'ai aucune idée de la manière dont je peux l'intégrer à mon application. Avez-vous des suggestions ?

package com.example.test.concurrency;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;

public class GracefulShutdownTest1 {
    final private int N;
    final private File f;
    public GracefulShutdownTest1(File f, int N) { this.f=f; this.N = N; }

    public void run()
    {
        PrintWriter pw = null;
        try {
            FileOutputStream fos = new FileOutputStream(this.f);
            pw = new PrintWriter(fos);
            for (int i = 0; i < N; ++i)
                writeBatch(pw, i);
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        finally
        {
            pw.close();
        }       
    }

    private void writeBatch(PrintWriter pw, int i) {
        for (int j = 0; j < 100; ++j)
        {
            int k = i*100+j;
            pw.write(Integer.toString(k));
            if ((j+1)%10 == 0)
                pw.write('\n');
            else
                pw.write(' ');
        }
    }

    static public void main(String[] args)
    {
        if (args.length < 2)
        {
            System.out.println("args = [file] [N] "
                    +"where file = output filename, N=batch count");
        }
        else
        {
            new GracefulShutdownTest1(
                    new File(args[0]), 
                    Integer.parseInt(args[1])
            ).run();
        }
    }
}

159voto

aioobe Points 158466

Vous pouvez faire ce qui suit :

  • Laissez le crochet d'arrêt définir un certain AtomicBoolean (ou booléen volatile) "keepRunning" à false.
  • (En option, .interrupt les threads de travail s'ils attendent des données dans un appel bloquant)
  • Attendez que les threads de travail (qui exécutent writeBatch dans votre cas) pour terminer, en appelant la fonction Thread.join() sur les fils de travail.
  • Mettre fin au programme

Un code sommaire :

  • Ajouter un static volatile boolean keepRunning = true;

  • Sur exécuter() vous passez à

    for (int i = 0; i < N && keepRunning; ++i)
        writeBatch(pw, i);
  • Sur main() vous ajoutez :

    final Thread mainThread = Thread.currentThread();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            keepRunning = false;
            mainThread.join();
        }
    });

C'est à peu près comme ça que je fais un "reject all clients upon hit Control-C" gracieux dans le terminal.


En les docs :

Lorsque la machine virtuelle commence sa séquence d'arrêt, elle lance tous les crochets d'arrêt enregistrés dans un ordre non spécifié et les laisse fonctionner simultanément. Lorsque tous les hooks sont terminés, il exécute tous les finaliseurs non provoqués si la finalisation à la sortie a été activée. Enfin, la machine virtuelle s'arrêtera.

En d'autres termes, un hook d'arrêt maintient la JVM en fonctionnement jusqu'à ce que le hook se termine (retour de la fonction exécuter() -Méthode.

-10voto

satish Points 1371

Les hooks d'arrêt sont des threads non démarrés qui sont enregistrés avec Runtime.addShutdownHook().JVM ne donne aucune garantie sur l'ordre dans lequel les hooks d'arrêt sont démarrés. http://techno-terminal.blogspot.in/2015/08/shutdown-hooks.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X