1. Pembuatan proses java
Java menyediakan dua metode untuk memulai proses atau program lain:
(1) Gunakan metode exec () runtime (2) Gunakan metode start processBuilder () (2)
1.1 ProcessBuilder
Kelas ProcessBuilder adalah kelas baru yang baru ditambahkan di Java.lang oleh J2SE 1.5. Sebelum J2SE 1.5, kontrol dan manajemen proses diimplementasikan oleh kelas proses.
Setiap instance ProcessBuilder mengelola satu set properti proses. Metode Start () menggunakan properti ini untuk membuat instance proses baru. Metode start () dapat dipanggil berulang kali dari contoh yang sama untuk membuat proses anak baru dengan sifat yang sama atau terkait.
Setiap generator proses mengelola properti proses ini:
Perintah adalah daftar string yang mewakili file program eksternal yang akan dipanggil dan parameternya (jika ada). Di sini, daftar string yang mewakili perintah sistem operasi yang valid tergantung pada sistem. Sebagai contoh, setiap variabel keseluruhan biasanya menjadi elemen dalam daftar ini, tetapi ada sistem operasi yang menginginkan program untuk menandai string baris perintah sendiri - dalam sistem tersebut, implementasi Java mungkin memerlukan perintah untuk memasukkan dengan tepat dua elemen ini.
Lingkungan adalah pemetaan yang bergantung pada sistem dari variabel ke nilai. Nilai awal adalah salinan dari lingkungan proses saat ini (lihat System.getEnv ()).
Direktori Bekerja. Nilai default adalah direktori kerja saat ini dari proses saat ini, biasanya dinamai sesuai dengan user.dir properti sistem.
Properti Redirecterrorstream. Awalnya, properti ini salah, yang berarti bahwa output standar dan output kesalahan dari proses anak dikirim ke dua aliran independen yang dapat diakses melalui metode. GetInputStream () dan Metode Process.getErrorStream (). Jika nilainya diatur ke True, kesalahan standar digabungkan dengan output standar. Ini membuatnya lebih mudah untuk mengaitkan pesan kesalahan dan output yang sesuai. Dalam hal ini, data gabungan dapat dibaca dari aliran yang dikembalikan oleh proses.getInputStream (), sedangkan aliran dibaca dari proses.getErrorStream () akan mencapai ujung file secara langsung.
Memodifikasi sifat -sifat pembangun proses akan mempengaruhi proses selanjutnya yang dimulai dengan metode start () objek, tetapi tidak akan pernah mempengaruhi proses yang sebelumnya memulai atau Java itu sendiri. Sebagian besar pemeriksaan kesalahan dilakukan dengan metode start (). Keadaan objek dapat dimodifikasi, tetapi mulai () akan gagal dengan cara ini. Misalnya, mengatur properti perintah ke daftar kosong tidak akan melempar pengecualian kecuali start () disertakan.
Perhatikan bahwa kelas ini tidak sinkron. Jika beberapa utas mengakses proses proses pada saat yang sama, dan setidaknya satu dari utas secara struktural memodifikasi salah satu properti, ia harus menyimpan sinkronisasi eksternal.
Ringkasan Metode Konstruksi
ProcessBuilder (Daftar <String> perintah)
Bangun generator proses menggunakan program dan parameter sistem operasi tertentu.
ProcessBuilder (Command ...
Bangun generator proses menggunakan program dan parameter sistem operasi tertentu.
Ringkasan metode
Daftar Command <string> ()
Mengembalikan program sistem operasi dan parameter generator proses ini.
Perintah ProcessBuilder (Daftar <String> perintah)
Mengatur program sistem operasi dan parameter generator proses ini.
Perintah ProcessBuilder (Perintah String ...
Mengatur program sistem operasi dan parameter generator proses ini.
Direktori File ()
Mengembalikan direktori kerja generator proses ini.
ProcessBuilder Directory (Direktori File)
Mengatur direktori kerja untuk generator proses ini.
Peta <string, string> lingkungan ()
Mengembalikan tampilan pemetaan string dari lingkungan generator proses ini.
boolean redirecterrorstream ()
Beri tahu generator proses apakah akan menggabungkan kesalahan standar dan output standar.
ProcessBuilder Redirecterrorstream (Boolean Redirecterrorstream)
Mengatur properti Redirecterrorstream dari generator proses ini.
Proses mulai ()
Mulai proses baru menggunakan properti generator proses ini.
1.2 Runtime
Setiap aplikasi Java memiliki instance kelas runtime, yang memungkinkan aplikasi untuk terhubung ke lingkungan yang dijalankan. Runtime saat ini dapat diperoleh melalui metode getRuntime.
Aplikasi tidak dapat membuat instance kelas runtime mereka sendiri. Namun, Anda bisa mendapatkan referensi ke objek runtime saat ini melalui metode getRuntime. Setelah Anda mendapatkan referensi ke objek runtime saat ini, Anda dapat memanggil metode objek runtime untuk mengontrol keadaan dan perilaku mesin virtual Java.
Kode koleksi kode java
void addshutdownhook (hook utas)
Daftarkan mesin virtual baru untuk mematikan kait.
int processors ()
Mengembalikan jumlah prosesor yang tersedia ke mesin virtual Java.
Proses EXEC (Perintah String)
Jalankan perintah string yang ditentukan dalam proses terpisah.
Proses Exec (String [] CMDarray)
Mengeksekusi perintah dan variabel yang ditentukan dalam proses terpisah.
Proses EXEC (String [] CMDArray, String [] Envp)
Mengeksekusi perintah dan variabel yang ditentukan dalam proses terpisah dari lingkungan yang ditentukan.
Proses EXEC (String [] CMDArray, String [] Envp, File Dir)
Jalankan perintah dan variabel yang ditentukan dalam proses terpisah di lingkungan yang ditentukan dan direktori kerja.
Proses EXEC (Perintah String, String [] Envp)
Jalankan perintah string yang ditentukan dalam proses terpisah dari lingkungan yang ditentukan.
Proses EXEC (Perintah String, String [] Envp, File Dir)
Jalankan perintah string yang ditentukan dalam proses terpisah dengan lingkungan dan direktori kerja yang ditentukan.
void exit (status int)
Hentikan mesin virtual Java yang sedang berjalan dengan memulai urutan shutdown dari mesin virtual.
panjang freememory ()
Mengembalikan jumlah memori bebas di mesin virtual Java.
membatalkan GC ()
Jalankan pengumpul sampah.
InputStream getLocalizedInputStream (inputstream in)
Usang. Dimulai dengan JDK 1.1, metode yang disukai untuk mengonversi aliran byte yang dikodekan secara lokal ke aliran karakter Unicode adalah menggunakan kelas InputStreamReader dan BufferedReader.
OutputStream getLocalizedOutputStream (outputStream out)
Usang. Dimulai dengan JDK 1.1, metode yang disukai untuk mengonversi aliran karakter unicode ke aliran byte yang disandikan secara lokal adalah menggunakan kelas OutputStreamWriter, bufferedWriter, dan printwriter.
runtime statis getRuntime ()
Mengembalikan objek runtime yang terkait dengan aplikasi Java saat ini.
void berhenti (status int)
Paksa mengakhiri mesin virtual Java yang sedang berjalan.
void load (nama file string)
Memuat nama file yang ditentukan sebagai pustaka dinamis.
void loadlibrary (string libname)
Memuat pustaka dinamis dengan nama perpustakaan yang ditentukan.
long maxmemory ()
Mengembalikan jumlah maksimum memori yang coba digunakan oleh mesin virtual Java.
Boolean Removeshutdownhook (Thread Hook)
Batalkan register mesin virtual yang sebelumnya terdaftar untuk mematikan kait.
membatalkan runfinalisasi ()
Menjalankan metode penghentian semua objek yang menangguhkan finalisasi.
runfinalizersonexit statis void (nilai boolean)
Usang. Metode ini sendiri tidak aman. Ini mungkin memanggil metode akhir pada objek yang digunakan, sementara utas lain beroperasi pada objek -objek tersebut, menghasilkan perilaku atau kebuntuan yang salah.
Total TotalMemory ()
Mengembalikan jumlah total memori di mesin virtual Java.
void traceInstruksi (boolean on)
Aktifkan/Nonaktifkan Pelacakan Perintah.
void tracemethodcalls (boolean on)
Aktifkan/Nonaktifkan Pelacakan Panggilan Metode.
1.3 proses
Tidak masalah metode mana yang digunakan untuk memulai proses, contoh kelas proses mewakili proses yang dimulai akan dikembalikan, yang dapat digunakan untuk mengontrol proses dan mendapatkan informasi yang relevan. Kelas proses menyediakan metode untuk dieksekusi dari input proses, output eksekusi untuk diproses, menunggu penyelesaian proses, memeriksa status keluar proses, dan menghancurkan (membunuh) proses:
void hancurkan ()
Bunuh proses anak.
Secara umum, metode ini tidak dapat membunuh proses yang telah dimulai, jadi lebih baik tidak menggunakannya.
int exitvalue ()
Mengembalikan nilai keluar dari proses anak.
Metode ExitValue () akan memiliki nilai pengembalian normal hanya setelah proses startup menyelesaikan eksekusi atau keluar karena pengecualian, jika tidak, pengecualian akan dilemparkan.
Inputstream getErrorStream ()
Mendapat aliran kesalahan dari proses anak.
Jika output kesalahan dialihkan, output kesalahan tidak dapat dibaca dari aliran.
InputStream getInputStream ()
Mendapat aliran input dari proses anak.
Output standar dari proses dapat dibaca dari aliran ini.
OutputStream getOutputStream ()
Mendapat aliran output dari proses anak.
Data yang ditulis ke aliran digunakan sebagai input standar untuk proses.
int waitfor ()
Menyebabkan utas saat ini menunggu, jika perlu, sampai proses yang diwakili oleh objek proses telah diakhiri.
2. Contoh Pemrograman Multi-Proses
Secara umum, ketika kami menjalankan metode di kelas lain di Java, apakah mereka adalah panggilan statis atau dinamis, mereka dieksekusi dalam proses saat ini, yaitu, hanya ada satu instance mesin virtual Java yang berjalan. Terkadang, kita perlu memulai beberapa subproses Java melalui kode Java. Meskipun melakukan ini mengambil beberapa sumber daya sistem, ini akan membuat program lebih stabil karena program yang baru dimulai berjalan dalam proses mesin virtual yang berbeda.
Di Java kita dapat menggunakan dua metode untuk mencapai persyaratan ini. Cara termudah adalah menjalankan java className melalui metode exec di runtime. Jika eksekusi berhasil, metode ini mengembalikan objek proses. Mari kita lihat contoh sederhana di bawah ini.
// test1.java impor java.io.*; Tes kelas publik {public static void main (string [] args) {fileoutputStream fout = new fileoutputStream ("c: // test1 .txt"); ; exec ("java test1");Setelah menjalankan program melalui java test_exec, saya menemukan bahwa ada file test1.txt tambahan pada drive C, tetapi informasi output "disebut dengan sukses!" Oleh karena itu, dapat disimpulkan bahwa tes telah dieksekusi dengan sukses, tetapi untuk beberapa alasan, informasi output tes bukan output di konsol test_exec. Alasan ini juga sangat sederhana, karena proses anak test_exec dibuat menggunakan eksekutif.
Jika Anda ingin mengeluarkan informasi output dari proses anak, Anda dapat memperoleh aliran output dari proses anak melalui proses getInputStream dalam proses (output dalam proses anak, input dalam proses induk), dan kemudian transfer aliran output anak Proses dari output konsol proses induk. Kode implementasi spesifik adalah sebagai berikut:
// test_exec_out.javaimport java.io.*; Kelas publik test_exec_out {public static void main (string [] args) {runtime run = runtime.getRuntime (); = BufferedInputStream (P.GetInputStream ()); ;}}Seperti yang dapat dilihat dari kode di atas, dalam test_exec_out.java, informasi output dari proses anak dibaca berdasarkan baris, dan kemudian output dilakukan pada setiap baris di test_exec_out. Diskusi di atas adalah cara mendapatkan informasi output dari proses anak. Kemudian, selain informasi output, ada juga informasi input. Karena proses anak tidak memiliki konsol sendiri, informasi input juga harus disediakan oleh proses induk. Kami dapat memberikan informasi input ke proses anak melalui metode proses getOutputStream (yaitu, informasi input dari proses induk ke proses anak, daripada memasukkan informasi dari konsol). Kita dapat melihat kode berikut:
// Test2.java Impor Java.io.*; Tes Kelas Publik {public static void main (String [] args) {BufferedReader Br = BufferedReader baru (inputStreamRead ER (System.in)); "Informasi yang dimasukkan oleh Proses Induk:" + Br.Readline ());}} // test_exec_in.javaimport java.io.*; Kelas publik test_exec_in {public static void main (string [] args) {run run run = runtime .getRuntime (); flush (); Dari kode di atas, kita dapat melihat bahwa test1 mendapatkan informasi yang dikirim oleh test_exec_in dan mengeluarkannya. Ketika Anda tidak menambahkan bw.flash () dan bw.close (), informasi tidak akan mencapai proses anak, yang berarti bahwa proses anak memasuki keadaan pemblokiran, tetapi karena proses induk telah keluar, proses anak juga keluar . Jika Anda ingin membuktikan ini, Anda dapat menambahkan System.in.read () di akhir dan kemudian melihat proses Java melalui Task Manager (di bawah Windows), dan Anda akan menemukan bahwa jika Anda menambahkan bw.flush () dan BW .close (), hanya satu proses Java, jika mereka dihapus, ada dua proses Java. Ini karena jika informasi diteruskan ke test2, test2 keluar setelah mendapatkan informasi. Berikut adalah satu hal yang harus dijelaskan bahwa eksekusi EXEC tidak sinkron dan tidak akan berhenti menjalankan kode berikut karena program tertentu yang dieksekusi diblokir. Oleh karena itu, setelah menjalankan test2, kode berikut masih dapat dieksekusi.
Metode EXEC telah dimuat ulang berkali -kali. Apa yang digunakan di atas hanyalah kelebihan bebannya. Ini juga dapat memisahkan perintah dan parameter, seperti exec ("java.test2") dapat ditulis sebagai exec ("java", "test2"). EXEC juga dapat menjalankan mesin virtual Java dengan konfigurasi yang berbeda melalui variabel lingkungan yang ditentukan.
Selain menggunakan metode EXEC Runtime untuk membangun proses anak, Anda juga dapat membangun proses anak melalui proses proses. Penggunaan ProcessBuilder adalah sebagai berikut:
// test_exec_out.javaimport java.io.*; Kelas publik test_exec_out {public static void main (string [] args) {ProcessBuilder pb = ProcessBui lder ("java", "test1"); ;……}}Dalam membangun proses anak, ProcessBuilder mirip dengan runtime. Setelah mendapatkan prosesnya, operasinya persis sama.
Seperti runtime, ProcessBuilder juga dapat mengatur informasi lingkungan, direktori kerja, dll. Dari file yang dapat dieksekusi. Contoh berikut menjelaskan cara mengatur informasi ini menggunakan ProcessBuilder.
ProcessBuilder pb = new ProcessBuilder ("command", "arg2", "arg2", '' '); // atur peta variabel lingkungan <string, string> env = pb.environment (); env.put ("key1", ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::: "value1")); env.remove ("key2"); env.put ("key2", env .get (Key1 ") +" _test ");