Kerangka kerja fork/gount adalah implementasi antarmuka ExecutorService, yang melaluinya kami dapat mengimplementasikan beberapa proses. Fork/Join dapat digunakan untuk secara rekursif membagi tugas besar menjadi beberapa tugas kecil, dengan tujuan memanfaatkan semua sumber daya penuh untuk meningkatkan kinerja aplikasi sebanyak mungkin.
Seperti implementasi antarmuka ExecutorService lainnya, Fork/Join juga menggunakan kumpulan utas untuk mengelola utas pekerja yang didistribusikan. Apa yang unik tentang kerangka kerja fork/gabungan adalah menggunakan algoritma pencucian kerja. Melalui algoritma ini, utas pekerja dapat mencuri tugas utas sibuk lainnya untuk dieksekusi ketika tidak ada yang bisa dilakukan.
Inti dari kerangka kerja fork/gount adalah kelas forkjoinpool, subclass dari abstractExecutorservice class. Forkjoinpool mengimplementasikan algoritma pencucian kerja inti dan dapat melakukan pemrosesan forkjointask.
Penggunaan dasar
Langkah pertama dalam menggunakan kerangka kerja garpu/gabungan adalah menulis kode yang melakukan tugas yang terfragmentasi. Kode yang akan ditulis mirip dengan pseudo-code berikut:
Jika tugasnya cukup kecil: jalankan tugas langsung: Potong tugas menjadi dua tugas kecil untuk menjalankan dua tugas kecil dan tunggu hasilnya
Gunakan subkelas forkjointask untuk merangkum kode seperti di atas. Biasanya, beberapa kelas yang disediakan oleh JDK digunakan, termasuk Recursivetask (kelas ini akan mengembalikan hasilnya) dan RecursiveAction.
Setelah menyiapkan subkelas forkjointask, buat objek yang mewakili semua tugas dan lewati ke metode Invoke () dari instance forkjoinpool.
Dari blur hingga jelas
Untuk membantu memahami cara kerja kerangka kerja garpu/bergabung, kami menggunakan kasus untuk menggambarkan: misalnya, mengaburkan sebuah gambar. Kami mewakili gambar menggunakan array integer, di mana setiap nilai numerik mewakili warna piksel. Gambar kabur juga diwakili oleh array dengan panjang yang sama.
Mengeksekusi Blur dicapai dengan memproses setiap piksel yang mewakili gambar. Hitung rata -rata masing -masing piksel dan piksel di sekitarnya (rata -rata dari tiga warna primer merah, kuning dan biru), dan array hasil yang dihasilkan adalah gambar kabur. Karena representasi gambar biasanya merupakan array besar, seluruh proses biasanya membutuhkan banyak waktu. Kerangka kerja garpu/gabungan dapat digunakan untuk memanfaatkan keuntungan dari pemrosesan bersamaan pada sistem multiprosesor untuk mempercepat. Berikut ini kemungkinan implementasi:
paket com.zhyea.robin; impor java.util.concurrent.recursiveAction; ForkBlur kelas publik memperluas RecursiveAction {private int [] msource; Private int mstart; Int Mlength Private; intr private [] mdestination; // Tangani ukuran jendela; itu harus menjadi angka ganjil. private int mblurwidth = 15; forkblur publik (int [] src, int start, int length, int [] dst) {msource = src; mstart = mulai; mlength = panjang; mdestination = dst; } void protected computedirectly () {int sidepixels = (mBlurwidth - 1) / 2; untuk (int index = mStart; index <mstart+mlength; index ++) {// Hitung nilai rata -rata. float rt = 0, gt = 0, bt = 0; untuk (int mi = -sidepixels; mi <= sidepixels; mi ++) {int mindex = math.min (math.max (mi+index, 0), msource.length - 1); int pixel = msource [mindex]; rt += (float) ((pixel & 0x00ff0000) >> 16) / mBlurwidth; gt += (float) ((pixel & 0x00000ff00) >> 8) / mblurwidth; bt += (float) ((pixel & 0x000000ff) >> 0) / mblurwidth; } // Reorganisasi piksel target. int dpixel = (0xff0000000) | (((int) rt) << 16) | (((int) gt) << 8) | (((int) bt) << 0); mdestination [index] = dpixel; }} ....}Sekarang terapkan metode abstrak komputasi (), di mana kedua operasi fuzzy diimplementasikan, dan membagi tugas menjadi dua tugas kecil diimplementasikan. Di sini kami hanya memutuskan apakah akan menjalankan tugas secara langsung atau membaginya menjadi dua tugas kecil berdasarkan panjang array:
statis statis yang dilindungi sthreshold = 100000; Protected void compute () {if (mlength <sthreshold) {computedirectly (); kembali; } int split = mLength / 2; Invokeall (New Forkblur (Msource, Mstart, Split, Mdestination), New Forkblur (Msource, Mstart + Split, Mlength - Split, Mdestination)); }Karena implementasi metode di atas didefinisikan dalam subkelas rekursiveAction, tugas dapat dibuat dan dijalankan langsung di forkjoinpool. Langkah -langkah spesifiknya adalah sebagai berikut:
1. Buat objek yang mewakili tugas yang akan dilakukan:
// SRC mewakili array piksel dari gambar sumber // DST mewakili piksel dari gambar yang dihasilkan forkblur fb = forkblur baru (src, 0, src.length, dst);
2. Buat instance forkjoinpool yang menjalankan tugas:
ForkJoinPool pool = new ForkJoinPool();
3. Jalankan tugas:
pool.invoke(fb);
Kode sumber juga berisi beberapa kode untuk membuat gambar target. Untuk detailnya, lihat contoh forkblur.
Implementasi Standar
Untuk menggunakan kerangka kerja fork/gabungan untuk menjalankan tugas bersamaan pada sistem multi-core sesuai dengan algoritma khusus, tentu saja, Anda perlu mengimplementasikan kelas khusus (seperti kelas forkblur yang kami terapkan sebelumnya). Selain itu, beberapa fitur kerangka kerja garpu/gabungan telah banyak digunakan di Javase. Misalnya, metode paralelsort () dari kelas java.util.arrays di java8 menggunakan kerangka kerja fork/gabungan. Untuk detailnya, silakan merujuk ke dokumentasi Java API.
Implementasi lain dari kerangka kerja garpu/gabungan berada di bawah paket java.util.streams, yang juga merupakan bagian dari fitur Lambda Java8.