Útmutató a java.lang.Process API-hoz

1. Bemutatkozás

Ebben az oktatóanyagban mi fogunk részt venni alapos áttekintés a Folyamat API.

Ahhoz, hogy sekélyebben megvizsgálja a használat módját Folyamat egy shell parancs végrehajtásához itt hivatkozhatunk előző oktatóanyagunkra.

A hivatkozott folyamat egy végrehajtó alkalmazás. A Folyamat osztály az e folyamatokkal való interakció módszereit tartalmazza, beleértve a kimenet kinyerését, a bemenet végrehajtását, az életciklus megfigyelését, a kilépési állapot ellenőrzését és megsemmisítését (megölését).

2. Használata Folyamat Osztály a Java program fordításához és futtatásához

Lássunk egy példát egy másik Java program fordítására és futtatására a segítségével Folyamat API:

A @Test public void, amikor "); process = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); BufferedReader output = new BufferedReader (új InputStreamReader (process.getInputStream ())); int érték = Integer.parseInt (output.readLine ()); assertEquals (3, érték); }

Így a Java kód futtatására szolgáló alkalmazások egy meglévő Java kódon belül gyakorlatilag korlátlanok.

3. Létrehozási folyamat

Java alkalmazásunk bármely olyan alkalmazást meghívhat, amely a számítógépes rendszerünkön fut, az operációs rendszer korlátozásainak alávetve.

Ezért tudjuk végrehajtani az alkalmazásokat. Lássuk, milyen különféle felhasználási esetek futtathatók a Process API használatával.

A ProcessBuilder osztály lehetővé teszi számunkra, hogy alfolyamatokat hozzunk létre alkalmazásunkon belül.

Nézzük meg a Windows-alapú Jegyzettömb alkalmazás megnyitásának bemutatóját:

ProcessBuilder builder = new ProcessBuilder ("notepad.exe"); Folyamatfolyamat = builder.start ();

4. Elpusztító folyamat

Folyamat módszereket is nyújt számunkra az alfolyamatok vagy folyamatok megsemmisítésére. Bár az alkalmazás elpusztítása platformfüggő.

Nézzük meg a különböző felhasználási eseteket, amelyek lehetségesek.

4.1. Egy folyamat megsemmisítése hivatkozással

Tegyük fel, hogy Windows operációs rendszert használunk, és szeretnénk létrehozni a Notepad alkalmazást, és megsemmisíteni.

A korábbiakhoz hasonlóan létrehozhatunk egy Jegyzettömb alkalmazást is a ProcessBuilder osztály és a Rajt() módszer.

Akkor felhívhatjuk a elpusztítani() módszer a mi Folyamat tárgy.

4.2. Folyamat megsemmisítése azonosítóval

Megölhetünk olyan operációs rendszerünkön futó folyamatokat is, amelyeket esetleg nem az alkalmazásunk hoz létre.

Óvatosan kell eljárni ennek során, mivel öntudatlanul elpusztíthatunk egy kritikus folyamatot, amely instabillá teheti az operációs rendszert.

Először meg kell találnunk az aktuális futó folyamat azonosítóját a feladatkezelő ellenőrzésével, és meg kell találnunk a pid-t.

Lássunk egy példát:

Opcionálisan választhatóProcessHandle = ProcessHandle.of (5232); választhatóProcessHandle.ifPresent (processHandle -> processHandle.destroy ()); 

4.3. Folyamat megsemmisítése erőszakkal

A. Végrehajtásáról elpusztítani() módszerrel az alfolyamatot megölik, amint azt a cikkben korábban láttuk.

Abban az esetben, amikor elpusztítani() nem működik, lehetőségünk van rá tönkreteszni ().

Mindig azzal kell kezdeni elpusztítani() módszer először. Ezt követően gyorsan elvégezhetjük az alfolyamat végrehajtását életben van().

Ha igazra tér vissza, akkor hajtsa végre tönkreteszni ():

ProcessBuilder builder = new ProcessBuilder ("notepad.exe"); Folyamatfolyamat = builder.start (); process.destroy (); if (process.isAlive ()) {process.destroyForcably (); }

5. Várakozás a folyamat befejezésére

Két túlterhelt módszerünk is van, amelyek révén biztosíthatjuk, hogy megvárhatjuk egy folyamat befejezését.

5.1. várni rá()

Amikor ezt a módszert végrehajtják, akkor helyére kerül az aktuális végrehajtási folyamat szála blokkolás-várakozás állapotban, hacsak az alfolyamat nem fejeződik be.

Vessünk egy pillantást a példára:

ProcessBuilder builder = new ProcessBuilder ("notepad.exe"); Folyamatfolyamat = builder.start (); assertThat (process.waitFor ()> = 0); 

A fenti példából láthatjuk, hogy az aktuális szál a végrehajtás folytatásához továbbra is várja az alfolyamat szálának végét. Amint az alfolyamat véget ér, az aktuális szál folytatja a végrehajtását.

5.2. waitfor (hosszú timeOut, TimeUnit idő)

Amikor ezt a módszert végrehajtják, akkor helyére kerül az aktuális végrehajtási folyamat szála blokkolás-várakozás állapotban, hacsak az alfolyamat nem fejeződik be, vagy elfogy az ideje.

Vessünk egy pillantást a példára:

ProcessBuilder builder = new ProcessBuilder ("notepad.exe"); Folyamatfolyamat = builder.start (); assertFalse (process.waitFor (1, TimeUnit.SECONDS));

A fenti példából láthatjuk, hogy az aktuális szál a végrehajtás folytatásához továbbra is várja az alfolyamat szálának végét, vagy ha a megadott időintervallum letelt.

Ha ezt a módszert végrehajtják, akkor az true logikai értéket adja vissza, ha az alfolyamat kilépett, vagy egy logikai értéket false, ha a várakozási idő letelt az alfolyamat kilépése előtt.

6. exitValue ()

Amikor ezt a módszert futtatják, az aktuális szál nem várja meg, hogy az alfolyamat leálljon vagy megsemmisüljön, azonban IllegalThreadStateException ha az alfolyamat nem szűnik meg.

Egy másik megoldás, ha az alfolyamatot sikeresen befejezték, ez a folyamat kilépési értékét eredményezi.

Bármely lehetséges pozitív egész szám lehet.

Nézzünk meg egy példát, amikor a exitValue () A method pozitív egész számot ad vissza, amikor az alfolyamat sikeresen befejeződött:

@Test public void givenSubProcess_whenCurrentThreadWillNotWaitIndefinitelyforSubProcessToEnd_thenProcessExitValueReturnsGrt0 () IOException {ProcessBuilder builder = new ProcessBuilder ("notepad.exe") dobja; Folyamatfolyamat = builder.start (); assertThat (process.exitValue ()> = 0); }

7. életben van()

Amikor szubjektív üzleti feldolgozást szeretnénk végrehajtani, függetlenül attól, hogy a folyamat él-e vagy sem.

Gyorsan ellenőrizhetjük, hogy a folyamat életben van-e, ami logikai értéket ad vissza.

Lássunk rá egy gyors példát:

ProcessBuilder builder = new ProcessBuilder ("notepad.exe"); Folyamatfolyamat = builder.start (); Szál.alszik (10000); process.destroy (); assertTrue (process.isAlive ());

8. Folyamatfolyamok kezelése

Alapértelmezés szerint a létrehozott alfolyamatnak nincs terminálja vagy konzolja. Az összes szokásos I / O (azaz stdin, stdout, stderr) műveletet elküldjük a szülői folyamatnak. Ezáltal a szülői folyamat felhasználhatja ezeket az adatfolyamokat az alfolyamat bemenetének és kimenetének megszerzéséhez.

Következésképpen ez hatalmas rugalmasságot biztosít számunkra, mivel kontrollt ad részfolyamatunk bemenete / kimenete felett.

8.1. getErrorStream ()

Érdekes módon lekérhetjük az alfolyamatból keletkezett hibákat, és ezáltal elvégezhetjük az üzleti feldolgozást.

Ezt követően specifikus üzleti feldolgozási ellenőrzéseket hajthatunk végre a követelményeink alapján.

Lássunk egy példát:

@Test public void givenSubProcess_whenEncounterError_thenErrorStreamNotNull () dob IOException {Process process = Runtime.getRuntime (). Exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9 \ process \ process \ java9 \ process "); BufferedReader error = new BufferedReader (új InputStreamReader (process.getErrorStream ())); String errorString = hiba.readLine (); assertNotNull (errorString); }

8.2. getInputStream ()

Meghívhatjuk az alfolyamat által generált kimenetet is, és felhasználhatjuk a szülő folyamaton belül, lehetővé téve ezzel az információk megosztását a folyamatok között:

@Test public void givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3 () dobja az IOException {Process process = Runtime.getRuntime (). Exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9 \ process \x Output "); process = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); BufferedReader output = new BufferedReader (új InputStreamReader (process.getInputStream ())); int érték = Integer.parseInt (output.readLine ()); assertEquals (3, érték); }

8.3. getOutputStream ()

A szülői folyamatból bemenetet küldhetünk egy alfolyamatba:

Writer w = new OutputStreamWriter (process.getOutputStream (), "UTF-8"); w.write ("küldés gyereknek \ n");

8.4. A folyamatfolyamok szűrése

Tökéletesen használható eset a szelektív futási folyamatokkal való interakcióra.

Folyamat lehetőséget nyújt számunkra a futó folyamatok szelektív szűrésére egy bizonyos predikátum alapján.

Ezt követően üzleti műveleteket hajthatunk végre ezen a szelektív folyamatkészleten:

@Test public void givenRunningProcesses_whenFilterOnProcessIdRange_thenGetSelectedProcessPid () {assertThat (((int) ProcessHandle.allProcesses () .filter (ph -> (ph.pid ()> 10000 && ph.pid () 0);}

9. Következtetés

Folyamat az operációs rendszer szintű interakciók hatékony osztálya. A terminálparancsok kiváltása, valamint alkalmazások indítása, figyelése és megölése.

Ha többet szeretne olvasni a Java 9 Process API-ról, nézze meg itt található cikkünket.

Mint mindig, a forrásokat is a Githubon találja meg.