java 8
API
Tout d'abord, regardons la classe Process
ensemble à partir de Java API Docs.
** Processus de classe ** java.lang.Object java.lang.Process
Les méthodes ProcessBuilder.start () et Runtime.exec créent un processus natif et renvoient une instance d'une sous-classe de Process que vous pouvez utiliser pour contrôler ou obtenir des informations sur ce processus. La classe Process fournit des méthodes pour entrer à partir du processus, sortir vers le processus, attendre que le processus se termine, vérifier l'état de fin du processus et détruire (terminer) le processus. Par exemple, un processus de traitement de fenêtre natif, un processus démon, un processus Win16 / DOS dans un environnement Microsoft Windows ou un script shell.
Par défaut, le sous-processus créé n'a pas son propre terminal ou console. Tout ce traitement d'entrée / sortie standard (c'est-à-dire entrée standard, sortie standard, erreur standard) est redirigé vers le processus parent, mais pour accéder à ces informations, utilisez les méthodes getOutputStream (), getInputStream () et getErrorStream (). Utilisez le flux récupéré à l'aide de. Le processus parent utilise ces flux pour envoyer des entrées et obtenir la sortie des sous-processus. Certaines plates-formes natives utilisent une taille de tampon limitée pour les flux d'E / S standard, donc si un sous-processus ne parvient pas à écrire un flux d'entrée ou à lire une sortie de flux, le sous-processus sera bloqué ou bloqué. Il y a une possibilité de devenir.
Si vous le souhaitez, vous pouvez également utiliser des méthodes de la classe ProcessBuilder pour rediriger l'entrée et la sortie des sous-processus.
Même s'il n'y a pas de référence à l'objet Process, le sous-processus ne sera pas arrêté et continuera à s'exécuter de manière asynchrone.
L'exécution du processus représenté par l'objet Process ne peut pas être asynchrone ou parallèle au processus Java propriétaire de l'objet Process.
Certaines plates-formes natives utilisent une taille limitée de tampon pour les flux d'E / S standard, donc si un sous-processus ne parvient pas à écrire un flux d'entrée ou à lire un flux de sortie, le sous-processus sera bloqué ou bloqué. Cela peut être dans un état.
La chose la plus importante à surveiller est la possibilité d'une impasse.
bad.java
Process p = Runtime.getRuntime().exec("cmd /c dir");
//Fait attendre le thread actuel jusqu'à la fin du processus.
//★★★ Si le flux de sortie standard a beaucoup de sortie, le processus sera bloqué ★★★
p.waitFor();
Les méthodes ProcessBuilder.start () et Runtime.exec créent un processus natif et renvoient une instance d'une sous-classe de Process que vous pouvez utiliser pour contrôler ou obtenir des informations sur ce processus.
Il fournit un moyen de contrôler le processus et d'obtenir des informations.
Pour éviter le blocage ci-dessus, lisez le flux de sortie standard et le flux d'erreur standard à partir de la JVM.
getInputStream
et [ getErrorStream
](https: // docs .oracle.com / javase / jp / 8 / docs / api / java / lang / Process.html # getErrorStream--) est disponible
demo.java
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line = null;
while ((line = br.readLine()) != null) {
//Vous n'êtes pas obligé de sortir
}
} catch (IOException e) {
e.printStackTrace();
}
Même s'il n'y a pas de référence à l'objet Process, le sous-processus ne sera pas arrêté et continuera à s'exécuter de manière asynchrone.
Compte tenu des instructions de la documentation de l'API, après avoir utilisé l'objet Process, le GC Java devrait libérer l'objet Process, mais c'est juste différent, il est toujours en cours d'exécution. Il est donc préférable d'appeler la méthode destroy ().
bad.java
Process p = Runtime.getRuntime().exec("cmd /c dir");
// p.destroy();★★★ Ne se termine pas ★★★
MainTest.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
//échantillon
public class MainTest {
public static void main(String[] args) throws IOException, InterruptedException {
Process p = Runtime.getRuntime().exec("cmd /c cd bin && java ProcessTest");
//Flux de sortie
new StreamThread(p.getInputStream(), "OUTPUT").start();
//Flux d'erreur
new StreamThread(p.getErrorStream(), "ERROR").start();
//Obtenir le résultat de l'exécution du processus
int result = p.waitFor();
p.destroy();
//Des données de sortie
System.out.println("■ Code de résultat de l'exécution:" + result);
}
}
//Fil de flux
class StreamThread extends Thread {
private InputStream in;
private String type;
public StreamThread(InputStream in, String type) {
this.in = in;
this.type = type;
}
@Override
public void run() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(in, "MS932"))) {
String line = null;
while ((line = br.readLine()) != null) {
//Journaux de sortie, etc.
System.out.println(type + ">" + line);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ProcessTest.java
public class ProcessTest {
public static void main(String[] args) {
for (int i = 1; i <= 1000; i++) {
//Sortie standard
System.out.println("Voici la sortie standard:" + i + "Tour.");
//Erreur standard
System.err.println("Ceci est une erreur standard:" + i + "Tour.");
}
}
}
Recommended Posts