Biaya memulai utas dalam sistem relatif tinggi karena melibatkan interaksi dengan sistem operasi. Keuntungan menggunakan kumpulan utas adalah meningkatkan kinerja. Ketika sistem berisi sejumlah besar utas bersamaan, itu akan menyebabkan penurunan tajam dalam kinerja sistem dan bahkan menyebabkan JVM macet. Jumlah maksimum utas dalam parameter kumpulan utas dapat mengontrol jumlah utas bersamaan dalam sistem untuk tidak melebihi berapa kali.
1. Kelas Executors Factory digunakan untuk menghasilkan kumpulan utas . Kelas pabrik ini berisi metode pabrik statis berikut untuk membuat kumpulan utas yang sesuai. Kumpulan utas yang dibuat adalah objek ExecutorService. Metode pengiriman objek atau menjalankan metode untuk menjalankan tugas runnable atau callable yang sesuai. Pool utas itu sendiri memanggil metode shutdown () untuk menghentikan kumpulan utas saat tidak lagi diperlukan. Setelah memanggil metode ini, kumpulan utas tidak akan lagi mengizinkan tugas ditambahkan, tetapi tidak akan mati sampai semua tugas yang ditambahkan telah dieksekusi.
1. NewCachedThreadPool () membuat kumpulan utas dengan fungsi caching dan mengirimkan utas yang dibuat oleh tugas (objek yang dapat dipanggil atau dapat dipanggil) dari kumpulan utas. Jika eksekusi selesai, itu akan di -cache ke CachedThreadpool untuk menggunakan tugas yang perlu dieksekusi nanti.
Impor java.util.concurrent.executorservice; import java.util.concurrent.executors; kelas publik cacheethreadpool {static class Task mengimplementasikan runnable {@override public run () {System.out.println (this + "" + thread.currentthread (). Thread.currentThread (). GetAllstackTraces (). Size ()); }} public static void main (string [] args) {executorService cacheethreadpool = executors.newcachedThreadpool (); // Tambahkan tiga tugas ke kumpulan utas terlebih dahulu untuk (int i = 0; i <3; i ++) {cachethreadpool.execute (Tugas baru ()); } // Setelah tiga utas dieksekusi, tambahkan tiga tugas ke kumpulan utas lagi coba {thread.sleep (3000); } catch (InterruptedException e) {E.PrintStackTrace (); } untuk (int i = 0; i <3; i ++) {cachethreadpool.execute (tugas baru ()); }}}Hasil eksekusi adalah sebagai berikut:
Cachethreadpool $ tugas@2d312eb9 pool-1-thread-1 allstacktraces peta ukuran: 7cachethreadpool $ tugas@59522b86 pool-1-thread-3 allstacktraces ukuran peta: 7cachethreadpool $ 73dbb8f Pool-1-thread-2 allstackpool $ 73dbb8f Pool-1-thread-2 AllStackPool $ 73DBB8F POOL-1-thread-2 AllStackpool $ 73DBB8F POOL-1-thread-2 Pool-1-Thread-3 Allstacktraces Peta Ukuran: 7Cachethreadpool $ Tugas@256d5600 Pool-1-thread-1 Allstacktraces Peta Ukuran: 7Cachethreadpool $ Tugas@7D1C5894 Pool-1-thread-2 Peta Peta: 7
Objek utas di kumpulan utas di -cache dan digunakan kembali ketika tugas baru dieksekusi. Namun, jika ada banyak konkurensi, kumpulan benang cache masih akan membuat banyak objek utas.
2. NewFixEdThreadPool (int nthreads) membuat kumpulan utas dengan sejumlah utas yang dapat digunakan kembali oleh utas.
impor java.util.concurrent.executorservice; import java.util.concurrent.executors; kelas publik FixedThreadpool {kelas statis Tugas mengimplementasikan runnable {@override public void run () {System.out.println (this + "" + thread.currentthread (). Thread.currentThread (). GetAllstackTraces (). Size ()); }} public static void main (string [] args) {executorService fixedThreadpool = executors.newfixedThreadpool (3); // Pertama tambahkan tiga tugas ke kumpulan utas untuk (int i = 0; i <5; i ++) {fixedThreadpool.execute (new new ()); } // Setelah tiga utas dieksekusi, tambahkan tiga tugas ke kumpulan utas lagi coba {thread.sleep (3); } catch (InterruptedException e) {E.PrintStackTrace (); } untuk (int i = 0; i <3; i ++) {fixedThreadpool.execute (Tugas baru ()); }}}Hasil Eksekusi:
Fixedthreadpool $ tugas@7045c12d pool-1-thread-2 AllStacktraces Peta Ukuran: 7fixedThreadpool $ Tugas@50fa0bef pool-1-thread-2 AllStackTraces Peta Ukuran: 7fixedThreadpool $ Tugas@CCB1870 Pool-thread-2 AllstackTraces Ukuran: 7fix-7fix-7fix-7fix-732-PoolPed-73 AllStacktraces Peta Ukuran: 7FixEdThreadPool $ Tugas@5bdeff18 Pool-1-thread-2 AllStacktraces Ukuran Peta: 7FixEdThreadpool $ Tugas@7d5554e1 Pool-1-thread-1 AllStackTraces Ukuran Peta: 7fixedThreadpool $ Tugas@24468092 Pool-AGRACE-AGRACE-AGRACES-3 UKURAN3 7fixedThreadPool $ Tugas@fa7b978 pool-1-thread-2 Allstacktraces Peta Ukuran: 7
3. NewsingLetHreadExecutor (), Buat kumpulan utas dengan hanya utas tunggal, yang setara dengan memanggil newfixedthreadpool (1)
4. NewsheduledThreadPool (int corepoolsize), membuat kumpulan utas dengan sejumlah utas yang ditentukan, yang dapat menjalankan utas setelah penundaan yang ditentukan. Anda juga dapat mengulangi utas dalam periode waktu tertentu, mengetahui bahwa Anda dapat memanggil shutdown () untuk menutup kumpulan utas.
Contohnya adalah sebagai berikut:
Impor java.util.concurrent.executors; impor java.util.concurrent.schedululExecutorService; import java.util.concurrent.timeunit; kelas publik dijadwalkan threadpool {static class Task mengimplementr "" + Thread.currentThread (). GetName () + "AllStackTraces Peta Ukuran:" + thread.currentThread (). GetallstackTraces (). Size ()); }} public static void main (string [] args) {jadwalExecutorService StorduledExecutorService = executors.newsChedulThreadPool (3); JadwalExecutorService.schedule (Tugas Baru (), 3, TimeUnit.Seconds); Terjadwal ExecutorService.ScheduleatFixedRate (Tugas Baru (), 3, 5, TimeUnit.Seconds); coba {thread.sleep (30 * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } TerjadwalExecutorService.shutdown (); }}Hasil operasi adalah sebagai berikut:
time 1458921795240 pool-1-thread-1 AllStackTraces map size: 6time 1458921795241 pool-1-thread-2 AllStackTraces map size: 6time 1458921800240 pool-1-thread-1 AllStackTraces map size: 7time 1458921805240 pool-1-thread-1 AllStackTraces map size: 7time 1458921810240 Pool-1-thread-1 Allstacktraces Peta Ukuran: 7Time 1458921815240 Pool-1-thread-1 Allstacktraces Peta Ukuran: 7 Waktu 1458921820240 Pool-1-Thread-1 Allstack-Traces Ukuran Peta: 7
Seperti yang dapat dilihat dari waktu berjalan, tugas dieksekusi dalam siklus 5 detik.
5. NEWSINGETHREADSCHEDULEDEXECUTOR () Membuat kumpulan utas dengan hanya satu utas, dan memanggil newscheduledThreadpool (1).
2. FORKJOINPOOL DAN FORKJOINTASK
FORKJOINPOOL adalah kelas implementasi ExecutorService. Ini mendukung membagi tugas menjadi beberapa tugas kecil dalam komputasi paralel, dan menggabungkan hasil perhitungan beberapa tugas kecil ke dalam hasil perhitungan total. Ini memiliki dua konstruktor
Forkjoinpool (int paralelisme) menciptakan forkjoinpool yang berisi benang paralelisme.
Forkjoinpool (), membuat forkjoinpool dengan menggunakan nilai pengembalian runtime.AvailableProcessors () metode sebagai parameter paralelisme.
Forkjointask mewakili tugas yang bisa paralel dan digabungkan. Ini adalah kelas abstrak yang mengimplementasikan antarmuka <T> di masa depan. Ini memiliki dua subclass abstrak, mewakili reaksi ulang tugas tanpa nilai pengembalian dan rekursivetask dengan nilai pengembalian. Anda dapat mewarisi dua kelas abstrak ini sesuai dengan kebutuhan spesifik untuk mengimplementasikan objek Anda sendiri, dan kemudian memanggil metode pengiriman Forkjoinpool untuk dieksekusi.
Contoh reaksi ulang adalah sebagai berikut, menerapkan output paralel dari 0-300 angka.
impor java.util.concurrent.forkjoinpool; impor java.util.concurrent.recursiveAction; impor java.util.concurrent.timeunit; Action Class PublicForkJointask {Static Class PrintTask memperluas RecursiveAction {private static int threshold = 50; start int pribadi; akhir int pribadi; public printTask (int start, int end) {this.start = start; this.end = end; } @Override Protected void compute () {if (end - start <threshold) {for (int i = start; i <end; i ++) {System.out.println (thread.currentThread (). GetName () + "" + i); }} else {int middle = (start + end) / 2; PrintTask kiri = printTask baru (mulai, tengah); PrintTask kanan = printTask baru (tengah, akhir); left.fork (); right.fork (); }}} public static void main (string [] args) {forkjoinpool pool = new forkjoinpool (); pool.submit (printTask baru (0, 300)); coba {pool.Awaittermination (2, TimeUnit.Seconds); } catch (InterruptedException e) {E.PrintStackTrace (); } pool.shutdown (); }}Setelah membagi tugas kecil, hubungi metode fork () dari tugas dan tambahkan ke forkjoinpool untuk dieksekusi secara paralel.
Contoh rekursivetask, mengimplementasikan perhitungan paralel dari 100 bilangan bulat untuk berjumlah. Pisahkan menjadi setiap 20 angka dan jumlahnya untuk mendapatkan hasilnya, dan gabungkan mereka ke hasil akhir di akhir.
impor java.util.random; impor java.util.concurrent.executionexception; impor java.util.concurrent.forkjoinpool; impor java.util.concurrent. {Private Static Final Int Threshold = 20; private int arr []; start int pribadi; akhir int pribadi; CalTask publik (int [] arr, int start, int end) {this.arr = arr; this.start = mulai; this.end = end; } @Override Protected Integer Compute () {int sum = 0; if (end - start <threshold) {for (int i = start; i <end; i ++) {sum+= arr [i]; } System.out.println (thread.currentThread (). GetName () + "sum:" + sum); jumlah pengembalian; } else {int middle = (start + end) / 2; CalTask Left = CalTask baru (ARR, Start, Middle); CalTask Right = CalTask baru (ARR, Middle, End); left.fork (); right.fork (); return left.join () + right.join (); }}} public static void main (string [] args) {int arr [] = new int [100]; Acak acak = acak baru (); int total = 0; untuk (int i = 0; i <arr.length; i ++) {int tmp = random.nextInt (20); total += (arr [i] = tmp); } System.out.println ("Total" + Total); Forkjoinpool pool = forkjoinpool baru (4); Future <Integer> Future = Pool.submit (CalTask baru (ARR, 0, ARR.Length)); coba {System.out.println ("Cal Hasil:" + Future.get ()); } catch (InterruptedException e) {E.PrintStackTrace (); } catch (executionException) e) {e.printstacktrace (); } pool.shutdown (); }}Hasil eksekusi adalah sebagai berikut:
total 912ForkJoinPool-1-worker-2 sum:82ForkJoinPool-1-worker-2 sum:123ForkJoinPool-1-worker-2 sum:144ForkJoinPool-1-worker-3 sum:119ForkJoinPool-1-worker-2 sum:106ForkJoinPool-1-worker-2 sum:128ForkJoinPool-1-worker-2 Jumlah: 121forkjoinpool-1-worker-3 Jumlah: 89cal Hasil: 912
Setelah subtugas dieksekusi, hubungi metode gabungan () dari tugas untuk mendapatkan hasil eksekusi Subtask, dan kemudian tambahkan untuk mendapatkan hasil akhir.