1.Création du processus Java
Java fournit deux méthodes pour démarrer un processus ou un autre programme:
(1) Utiliser la méthode Exec () de Runtime (2) Utiliser la méthode START () de ProcessBuilder (2)
1.1 ProcessBuilder
La classe ProcessBuilder est une nouvelle classe nouvellement ajoutée dans Java.lang par J2SE 1.5. Avant J2SE 1.5, le contrôle et la gestion des processus ont été mis en œuvre par la classe de processus.
Chaque instance ProcessBuilder gère un ensemble de propriétés de processus. La méthode start () utilise ces propriétés pour créer une nouvelle instance de processus. La méthode start () peut être appelée à plusieurs reprises à partir de la même instance pour créer un nouveau processus enfant avec les mêmes propriétés ou associées.
Chaque générateur de processus gère ces propriétés de processus:
Une commande est une liste de chaînes qui représentent le fichier de programme externe à appeler et ses paramètres (le cas échéant). Ici, la liste des chaînes représentant des commandes de système d'exploitation valides dépend du système. Par exemple, chaque variable globale devient généralement un élément de cette liste, mais il existe des systèmes d'exploitation qui souhaitent que le programme marque les chaînes de ligne de commande eux-mêmes - dans ces systèmes, les implémentations Java peuvent nécessiter des commandes pour inclure exactement ces deux éléments.
Les environnements sont des mappages dépendants du système des variables aux valeurs. La valeur initiale est une copie de l'environnement de processus actuel (voir System.Gettenv ()).
Répertoire de travail. La valeur par défaut est le répertoire de travail actuel du processus actuel, généralement nommé selon la propriété système user.dir.
Propriété RedireCterRorstream. Initialement, cette propriété est fausse, ce qui signifie que la sortie standard de sortie et d'erreur du processus de l'enfant est envoyée à deux flux indépendants qui peuvent être accessibles via les méthodes process.getInputStream () et process.getorRorStream (). Si la valeur est définie sur true, l'erreur standard est fusionnée avec la sortie standard. Cela facilite l'associé des messages d'erreur et la sortie correspondante. Dans ce cas, les données fusionnées peuvent être lues à partir du flux renvoyé par process.getInputStream (), tandis que le flux lu à partir de process.GetErrorStream () atteindra directement la fin du fichier.
La modification des propriétés du générateur de processus affectera les processus ultérieurs lancés par la méthode start () de l'objet, mais n'affectera jamais les processus précédemment démarrés ou Java lui-même. La plupart des vérifications d'erreur sont effectuées par la méthode start (). L'état de l'objet peut être modifié, mais start () échouera de cette manière. Par exemple, la définition de la propriété de commande sur une liste vide ne lancera pas d'exception à moins que start () soit incluse.
Notez que cette classe n'est pas synchrone. Si plusieurs threads accèdent à un procédé en même temps, et qu'au moins l'un des threads modifie structurellement l'une des propriétés, elle doit maintenir une synchronisation externe.
Résumé des méthodes de construction
ProcessBuilder (Commande <string>)
Construisez un générateur de processus à l'aide de programmes et de paramètres de système d'exploitation spécifié.
ProcessBuilder (String ... Commande)
Construisez un générateur de processus à l'aide de programmes et de paramètres de système d'exploitation spécifié.
Résumé de la méthode
List <string> commande ()
Renvoie les programmes et paramètres du système d'exploitation de ce générateur de processus.
Commande ProcessBuilder (Commande <string>)
Définit les programmes et paramètres du système d'exploitation de ce générateur de processus.
Commande ProcessBuilder (String ... Commande)
Définit les programmes et paramètres du système d'exploitation de ce générateur de processus.
Répertoire de fichiers ()
Renvoie le répertoire de travail de ce générateur de processus.
Directory ProcessBuilder (répertoire de fichiers)
Définit le répertoire de travail pour ce générateur de processus.
Map <string, string> Environment ()
Renvoie une vue de mappage de chaînes de cet environnement de générateur de processus.
booléen redirectterRorstream ()
Informer le générateur de processus si fusionner les erreurs standard et la sortie standard.
ProcessBuilder RedireCterRorstream (Boolean RedirectorRorstream)
Définit la propriété RedireCterRorstream de ce générateur de processus.
Procédé start ()
Démarrez un nouveau processus en utilisant les propriétés de ce générateur de processus.
1.2 Runtime
Chaque application Java a une instance de classe d'exécution, permettant à l'application de se connecter à l'environnement qu'il exécute. Le temps d'exécution actuel peut être obtenu via la méthode GetRuntime.
Les applications ne peuvent pas créer leurs propres instances de classe d'exécution. Cependant, vous pouvez obtenir la référence à l'objet d'exécution actuel via la méthode GetRuntime. Une fois que vous avez obtenu une référence à l'objet d'exécution actuel, vous pouvez appeler la méthode de l'objet d'exécution pour contrôler l'état et le comportement de la machine virtuelle Java.
Code de collecte de code Java
void addShutdownHook (thread hook)
Enregistrez une nouvelle machine virtuelle pour éteindre le crochet.
int disponiblesprocessors ()
Renvoie le nombre de processeurs disponibles dans la machine virtuelle Java.
Processus Exec (commande String)
Exécutez la commande String spécifiée dans un processus distinct.
Process exec (String [] cmdArray)
Exécutez des commandes et des variables spécifiées dans un processus distinct.
Process exec (String [] cmdArray, String [] envp)
Exécutez des commandes et des variables spécifiées dans un processus distinct de l'environnement spécifié.
Process exec (String [] cmdArray, String [] envp, file dir)
Exécutez des commandes et des variables spécifiées dans des processus distincts dans le répertoire environnement et fonctionnel spécifié.
Process exec (String Commande, String [] envp)
Exécutez la commande String spécifiée dans un processus distinct de l'environnement spécifié.
Process exec (String Commande, String [] envp, file dir)
Exécutez la commande String spécifiée dans un processus distinct avec un environnement spécifié et un répertoire de travail.
Vide Exit (status int)
Terminez la machine virtuelle Java en cours d'exécution en démarrant la séquence d'arrêt de la machine virtuelle.
Long FreeMemory ()
Renvoie la quantité de mémoire libre dans la machine virtuelle Java.
void gc ()
Exécutez le collecteur des ordures.
InputStream getLocalizedInputStream (InputStream in)
Obsolète. À partir de JDK 1.1, la méthode préférée pour convertir un flux d'octet codé localement en flux de caractères Unicode est d'utiliser les classes InputStreamReader et BufferedReader.
OutputStream getLocalizedOutStream (OutputStream Out)
Obsolète. En commençant par JDK 1.1, la méthode préférée pour convertir un flux de caractères Unicode en un flux d'octet codé localement consiste à utiliser les classes OutputStreamWriter, BufferedWriter et PrintWriter.
GetRuntime d'exécution statique ()
Renvoie l'objet d'exécution associé à l'application Java actuelle.
vide halt (status int)
Terminez forcé la machine virtuelle Java en cours d'exécution.
vide charge (nom de fichier de chaîne)
Charge le nom de fichier spécifié en tant que bibliothèque dynamique.
void LoadLibrary (String libname)
Charge une bibliothèque dynamique avec le nom de la bibliothèque spécifiée.
long maxmemory ()
Renvoie la quantité maximale de mémoire que la machine virtuelle Java essaie d'utiliser.
booléen reposhutdownhook (thread hook)
Décorez une machine virtuelle précédemment enregistrée pour éteindre le crochet.
void runfinalisation ()
Exécute la méthode de terminaison de tous les objets qui suspend la finalisation.
statique void runfinalisersonexit (valeur booléenne)
Obsolète. Cette méthode elle-même est dangereuse. Il peut appeler une méthode finale sur l'objet utilisé, tandis que d'autres threads fonctionnent sur ces objets, ce qui entraîne un comportement incorrect ou des impasses.
Long TotalMemory ()
Renvoie la quantité totale de mémoire dans la machine virtuelle Java.
void traceinstructions (booléen)
Activer / désactiver le suivi des commandes.
tracethodcaux vides (booléen)
Activer / désactiver le suivi des appels de la méthode.
1.3 Processus
Quelle que soit la méthode utilisée pour démarrer le processus, une instance de la classe de processus représente le processus démarré sera retourné, qui peut être utilisé pour contrôler le processus et obtenir des informations pertinentes. La classe de processus fournit des méthodes pour exécuter à partir de l'entrée du processus, une sortie d'exécution pour le processus, attendre l'achèvement du processus, vérifier l'état de sortie du processus et détruire (tuer) le processus:
void destroy ()
Tuez le processus de l'enfant.
De manière générale, cette méthode ne peut pas tuer le processus qui a été démarré, il vaut donc mieux ne pas l'utiliser.
int exitValue ()
Renvoie la valeur de sortie du processus enfant.
La méthode eXitValue () n'aura une valeur de retour normale qu'après que le processus de démarrage a terminé son exécution ou quitté en raison d'une exception, sinon une exception sera lancée.
ENTROWSTREAM GETERORRORSTREAM ()
Obtient le flux d'erreur du processus enfant.
Si la sortie d'erreur est redirigée, la sortie d'erreur ne peut pas être lue à partir du flux.
InputStream getInputStream ()
Obtient le flux d'entrée du processus enfant.
La sortie standard du processus peut être lue à partir de ce flux.
OutputStream getOutputStream ()
Obtient le flux de sortie du processus enfant.
Les données écrites au flux sont utilisées comme entrée standard dans le processus.
int waitfor ()
Fait attendre le thread actuel, si nécessaire, jusqu'à ce que le processus représenté par l'objet de processus se termine.
2. Exemples de programmation multi-processus
Généralement, lorsque nous exécutons des méthodes dans d'autres classes en Java, qu'ils soient des appels statiques ou dynamiques, ils sont exécutés dans le processus actuel, c'est-à-dire qu'il n'y a qu'une seule instance de machine virtuelle Java. Parfois, nous devons démarrer plusieurs sous-processus Java via le code Java. Bien que cela ait des ressources système, cela rendra le programme plus stable car le programme nouvellement démarré s'exécute dans différents processus de machine virtuelle.
En Java, nous pouvons utiliser deux méthodes pour atteindre cette exigence. Le moyen le plus simple consiste à exécuter Java ClassName via la méthode EXEC dans l'exécution. Si l'exécution est réussie, cette méthode renvoie un objet de processus. Jetons un coup d'œil à un exemple simple ci-dessous.
// test1.java Importation de fichiers java.io. *; Public class test {public static void main (String [] args) {fileoutputStream fout = new FileOutputStream ("c: // test1 .txt"); ; exec ("Java test1");Après avoir exécuté le programme via Java test_exec, j'ai constaté qu'il y avait un fichier Test1.txt supplémentaire sur le lecteur C, mais les informations de sortie "appelées réussies!" Par conséquent, on peut conclure que le test a été exécuté avec succès, mais pour une raison quelconque, les informations de sortie du test ne sont pas sorties dans la console de test_exec. Cette raison est également très simple, car le processus d'enfant de Test_Exec est créé à l'aide de l'exécutif.
Si vous souhaitez produire les informations de sortie du processus de l'enfant, vous pouvez obtenir le flux de sortie du processus de l'enfant via GetInputStream dans le processus (sortie dans le processus de l'enfant, entrée dans le processus parent), puis transférer le flux de sortie de l'enfant processus à partir de la sortie de la console du processus parent. Le code d'implémentation spécifique est le suivant:
// test_exec_out.javaimport java.io. *; Classe publique test_exec_out {public static void main (string [] args) {runtime run = runtime.getRuntime (); = new BufferedInputStream (p.getInputStream ()); ;Comme on peut le voir à partir du code ci-dessus, dans test_exec_out.java, les informations de sortie du processus enfant sont lues par ligne, puis la sortie est effectuée sur chaque ligne dans test_exec_out. La discussion ci-dessus est de savoir comment obtenir les informations de sortie du processus de l'enfant. Ensuite, en plus des informations de sortie, il existe également des informations d'entrée. Étant donné que le processus enfant n'a pas sa propre console, les informations d'entrée doivent également être fournies par le processus parent. Nous pouvons fournir des informations d'entrée au processus de l'enfant via la méthode de processus GetOutputStream (c'est-à-dire les informations d'entrée du processus parent au processus enfant, plutôt que des informations d'entrée de la console). Nous pouvons consulter le code suivant:
// Test2.Java File Import Java.io. *; Public Class Test {public static void main (String [] args) {BufferedReader br = new BufferedReader (new inputStreamRead er (System.in)); "Informations saisies par le processus parent:" + br.readline ());}} // test_exec_in.javaimport java.io. .getRunttime (); flush (); bw.close (); À partir du code ci-dessus, nous pouvons voir que Test1 obtient les informations envoyées par test_exec_in et les publie. Lorsque vous n'ajoutez pas bw.flash () et bw.close (), les informations n'atteindront pas le processus de l'enfant, ce qui signifie que le processus de l'enfant entre dans un état de blocage, mais comme le processus parent est sorti, le processus de l'enfant sort également . Si vous souhaitez le prouver, vous pouvez ajouter System.in.read () à la fin, puis afficher le processus Java via le gestionnaire de tâches (sous Windows), et vous constaterez que si vous ajoutez BW.Flush () et BW .Close (), un seul processus Java existe, s'ils sont supprimés, deux processus Java existent. En effet, si les informations sont transmises à Test2, Test2 sort après avoir obtenu les informations. Voici une chose à expliquer que l'exécution de l'exec est asynchrone et n'arrêtera pas d'exécuter le code suivant car un certain programme exécuté est bloqué. Par conséquent, après l'exécution de Test2, le code suivant peut toujours être exécuté.
La méthode Exec a été rechargée plusieurs fois. Ce qui est utilisé ci-dessus n'est qu'une surcharge de celui-ci. Il peut également séparer les commandes et les paramètres, tels que Exec ("java.test2") peut être écrit en tant qu'EXEC ("java", "test2"). EXEC peut également exécuter des machines virtuelles Java avec différentes configurations via des variables d'environnement spécifiées.
En plus d'utiliser la méthode EXEC de Runtime pour créer un processus enfant, vous pouvez également créer un processus enfant via ProcessBuilder. L'utilisation de ProcessBuilder est la suivante:
// test_exec_out.javaimport java.io. *; Classe publique test_exec_out {public static void main (string [] args) {processBuilder pb = new ProcessBui lder ("java", "test1"); ;En établissant des processus enfants, ProcessBuilder est similaire à l'exécution. Après avoir obtenu le processus, leurs opérations sont exactement les mêmes.
Comme l'exécution, ProcessBuilder peut également définir les informations de l'environnement, le répertoire de travail, etc. du fichier exécutable. L'exemple suivant décrit comment définir ces informations à l'aide de ProcessBuilder.
ProcessBuilder pb = new ProcessBuilder ("Command", "arg2", "arg2", ''); // définir la carte de variable d'environnement <String, String> Env = pb.environment (); env.put ("key1", : :::::::::::::::::::::::::::::::::::- : :::::::::::::::::::::::::::::::::::- ::::::::::::::::::::::::::::::::: "Value1"); Env.Remove ("key2"); env.put ("key2", env. .get ("key1") + "_test");