cari
RumahOperasi dan penyelenggaraanKeselamatanBagaimana untuk menyelesaikan masalah menggunakan ParallelStream

Contohnya, coretan kod di bawah membuatkan orang membacanya seperti membaca puisi. Tetapi jika ia tidak digunakan dengan betul, ia boleh membawa maut.

List<integer> transactionsIds = widgets.stream()              .filter(b -> b.getColor() == RED)              .sorted((x,y) -> x.getWeight() - y.getWeight())              .mapToInt(Widget::getWeight)              .sum();</integer>

Kod ini mempunyai fungsi utama, iaitu strim. Menggunakannya, kita boleh menukar senarai biasa kepada strim, dan kemudian menggunakan saluran paip untuk memproses senarai. Secara keseluruhannya, semua yang saya gunakan mengatakan ia bagus.

Tidak terlalu biasa dengan fungsi ini? Anda boleh merujuk kepada: "Terdapat peta dan Peta rata di mana-mana, apakah maksudnya

Persoalannya akan datang

Bagaimana jika Apakah yang akan berlaku jika kita menggantikan strim dengan parallelStream?

Mengikut maksud literal, strim akan berubah daripada bersiri kepada selari.

Memandangkan bahawa ini adalah situasi selari, jelas terdapat isu keselamatan rangkaian. Walau bagaimanapun, apa yang kita bincangkan di sini bukanlah keperluan untuk menggunakan koleksi selamat benang, kerana topik ini terlalu asas. Pada zaman ini, belajar menggunakan koleksi selamat benang dalam situasi tidak selamat benang telah menjadi kemahiran penting.

Perangkap kali ini ialah isu prestasi penstriman selari.

Kami membiarkan kod bercakap.

Kod berikut mendayakan 8 utas pada masa yang sama dan semua utas menggunakan aliran selari untuk pengiraan data. Dalam logik pelaksanaan, kami membiarkan setiap tugasan tidur selama 1 saat, supaya kami boleh mensimulasikan menunggu yang memakan masa beberapa permintaan I/O.

Menggunakan strim, program akan kembali selepas 30 saat, tetapi kami menjangkakan program itu akan kembali dalam masa lebih daripada 1 saat kerana ia adalah aliran selari dan layak mendapat gelaran ini.

Ujian mendapati kami menunggu lama sebelum tugasan selesai.

static void paralleTest() {     List<integer> numbers = Arrays.asList(             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,             20, 21, 22, 23, 24, 25, 26, 27, 28, 29     );     final long begin = System.currentTimeMillis();     numbers.parallelStream().map(k -> {         try {             Thread.sleep(1000);             System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread());         } catch (InterruptedException e) {             e.printStackTrace();         }         return k;     }).collect(Collectors.toList()); }  public static void main(String[] args) { //    System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start(); }</integer>

Pits

Sebenarnya, kod ini mengambil masa yang berbeza apabila dilaksanakan pada mesin yang berbeza.

Oleh kerana ia selari, mesti ada tahap keselarian. Jika tahap keselarian terlalu rendah, keupayaannya tidak akan digunakan; jika tahap keselarian terlalu tinggi, masa penukaran konteks akan terbuang. Saya sangat kecewa apabila mendapati ramai pembangun kanan, yang mengetahui pelbagai parameter kumpulan benang mengikut hati, dan semua jenis penalaan, berani menutup mata dan menggunakan parallelStream dalam perniagaan intensif I/O.

Untuk memahami tahap paralelisme ini, kita perlu melihat kaedah pembinaan khusus. Cari kod seperti ini dalam kelas ForkJoinPool.

try {  // ignore exceptions in accessing/parsing properties     String pp = System.getProperty         ("java.util.concurrent.ForkJoinPool.common.parallelism");     if (pp != null)         parallelism = Integer.parseInt(pp);     fac = (ForkJoinWorkerThreadFactory) newInstanceFromSystemProperty(         "java.util.concurrent.ForkJoinPool.common.threadFactory");     handler = (UncaughtExceptionHandler) newInstanceFromSystemProperty(         "java.util.concurrent.ForkJoinPool.common.exceptionHandler"); } catch (Exception ignore) { }  if (fac == null) {     if (System.getSecurityManager() == null)         fac = defaultForkJoinWorkerThreadFactory;     else // use security-managed default         fac = new InnocuousForkJoinWorkerThreadFactory(); } if (parallelism  MAX_CAP)     parallelism = MAX_CAP;

Seperti yang anda lihat, tahap keselarian dikawal oleh parameter berikut. Jika parameter ini tidak dapat diperoleh, keselarian bilangan CPU - 1 akan digunakan secara lalai.

Seperti yang anda lihat, fungsi ini direka untuk perniagaan intensif pengkomputeran. Apabila anda memberikan terlalu banyak tugas kepadanya, pelaksanaan selarinya merosot kepada kesan seperti bersiri.

-Djava.util.concurrent.ForkJoinPool.common.parallelism=N

Walaupun anda menetapkan saiz awal menggunakan -Djava.util.concurrent.ForkJoinPool.common.parallelism=N, ia masih menghadapi masalah.

Setelah ditetapkan, pembolehubah selari ditetapkan kepada muktamad dan pengubahsuaian adalah dilarang. Dalam erti kata lain, parameter di atas hanya akan berkuat kuasa sekali.

Zhang San boleh menggunakan kod berikut dan menetapkan saiz selari kepada 20.

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");

John Doe mungkin telah menetapkan nilai ini kepada 30 dengan cara yang sama. Untuk menentukan nilai yang digunakan dalam projek anda, anda perlu bertanya kepada JVM cara memuatkan maklumat kelas.

Kaedah ini tidak begitu boleh dipercayai.

Penyelesaian

Kami boleh mencapai pelbagai jenis pengasingan tugas dengan menyediakan forkjoinpool luaran, iaitu menukar kaedah penyerahan.

Kod adalah seperti berikut Melalui penyerahan kod yang jelas, pengasingan tugas boleh dicapai.

ForkJoinPool pool = new ForkJoinPool(30);  final long begin = System.currentTimeMillis(); try {     pool.submit(() ->             numbers.parallelStream().map(k -> {                 try {                     Thread.sleep(1000);                     System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread());                 } catch (InterruptedException e) {                     e.printStackTrace();                 }                 return k;             }).collect(Collectors.toList())).get(); } catch (InterruptedException e) {     e.printStackTrace(); } catch (ExecutionException e) {     e.printStackTrace(); }

Dengan cara ini, senario yang berbeza boleh mempunyai darjah selari yang berbeza. Terdapat persamaan antara pengurusan sumber manual dengan cara ini dan CountDownLatch, mereka mempunyai tujuan yang sama.

Atas ialah kandungan terperinci Bagaimana untuk menyelesaikan masalah menggunakan ParallelStream. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Artikel ini dikembalikan pada:亿速云. Jika ada pelanggaran, sila hubungi admin@php.cn Padam

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

MinGW - GNU Minimalis untuk Windows

MinGW - GNU Minimalis untuk Windows

Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.