Strim Selari: Prestasi dan Perangkap
Dayakan strim selari, fahami kumpulan thread umum dan elakkan pepijat keadaan boleh ubah yang dikongsi.
Strim Selari: Prestasi dan Perangkap ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.
Mendayakan Strim Selari
Panggil .parallel() pada mana-mana strim atau gunakan Collection.parallelStream(). Operasi strim dijalankan dalam ForkJoinPool umum (lalai: teras CPU - 1 utas).
long count = list.parallelStream()
.filter(n -> n % 2 == 0)
.count();
System.out.println(count);Bila Strim Selari Berbaloi
Strim selari berbaloi apabila: set data besar (100,000+ elemen), operasi pada setiap elemen memerlukan pengiraan yang berat, dan saluran pemprosesan tidak mempunyai keadaan serta tidak bergantung pada susunan.
// Good candidate: CPU-heavy computation on large dataset
long sum = LongStream.rangeClosed(1, 10_000_000)
.parallel()
.filter(n -> isPrime(n))
.sum();
System.out.println(sum);Bila TIDAK Menggunakan Strim Selari
Elakkan strim selari untuk: koleksi kecil, operasi yang terikat pada input/output (operasi ini menyekat utas ForkJoinPool), operasi berkeadaan (pengisihan, penyingkiran pendua), atau apabila susunan penting dan mahal untuk dipulihkan.
// Bad: I/O bound — blocking ForkJoinPool threads starves other tasks
List<String> result = urls.parallelStream()
.map(url -> httpGet(url)) // BLOCKS the common pool
.collect(Collectors.toList());Pepijat Keadaan Boleh Ubah Dikongsi
Strim selari menjalankan operasi pada berbilang utas secara serentak. Mengubah suai koleksi boleh ubah yang dikongsi menyebabkan perlumbaan data dan hasil yang tidak betul.
// RACE CONDITION — never do this:
List<Integer> results = new ArrayList<>(); // not thread-safe
numbers.parallelStream().forEach(n -> results.add(n)); // corrupts list!
// Fix:
List<Integer> safe = numbers.parallelStream().collect(Collectors.toList());Operasi Berkeadaan: sorted dan Penyingkiran Pendua
sorted() dan distinct() perlu melihat semua elemen sebelum menghasilkan output, lalu mengehadkan keselarian dan sering menjadikan pemprosesan selari lebih perlahan daripada pemprosesan berjujukan.
// sorted() forces collect-all, then sort — parallel overhead usually not worth it:
list.parallelStream().sorted().collect(Collectors.toList());Operasi Sensitif terhadap Susunan
findFirst() dan forEachOrdered() mengekalkan susunan pertemuan dalam strim selari, lalu menambah kos penyegerakan. Gunakan findAny() atau forEach() apabila susunan tidak penting.
// Faster in parallel (order-insensitive):
Optional<Integer> any = list.parallelStream().filter(n -> n > 10).findAny();
// Slower in parallel (must preserve order):
Optional<Integer> first = list.parallelStream().filter(n -> n > 10).findFirst();Memilih Saiz Kumpulan Utas
ForkJoinPool umum menggunakan Runtime.getRuntime().availableProcessors() - 1 utas. Jalankan strim selari pada kumpulan tersuai dengan menyerahkannya dari dalam panggilan ForkJoinPool.invoke().
ForkJoinPool custom = new ForkJoinPool(8);
long result = custom.submit(
() -> LongStream.rangeClosed(1, 1_000_000).parallel().sum()
).get();Mengukur Prestasi Selari Berbanding Berjujukan
Sentiasa ukur prestasi dengan JMH menggunakan saiz data yang realistik. Overhed selari (pembahagian, penyelarasan utas, penggabungan) hanya wajar apabila masa pengiraan jauh melebihi overhed tersebut.
@Benchmark
public long sequential() { return LongStream.rangeClosed(1,1_000_000).sum(); }
@Benchmark
public long parallel() { return LongStream.rangeClosed(1,1_000_000).parallel().sum(); }Operasi Pengurangan dengan Pemprosesan Selari
reduce() dan collect() direka untuk berfungsi dengan betul secara selari apabila operasi bersifat bersekutu dan nilai identiti adalah betul.
// Associative reduce — safe in parallel:
int sum = list.parallelStream().reduce(0, Integer::sum);
// Non-associative: subtraction — NOT safe in parallel:
int bad = list.parallelStream().reduce(0, (a, b) -> a - b); // wrong result!Keupayaan untuk Dipecahkan Penting
Strim selari memecahkan sumber data menggunakan Spliterator. ArrayList dan tatasusunan dipecahkan dalam O(1); LinkedList dan HashSet sukar dipecahkan, lalu mengurangkan kecekapan selari.
Ringkasan: Senarai Semak Strim Selari
Sebelum menggunakan pemprosesan selari: (1) set data besar, (2) operasi terikat CPU, (3) tiada keadaan boleh ubah yang dikongsi, (4) tidak sensitif terhadap susunan, (5) sumber yang boleh dipecahkan (tatasusunan/ArrayList). Jika ragu-ragu, ukur prestasi.
Semakan Pantas
Apakah yang berlaku apabila anda menambah elemen pada koleksi yang tidak selamat untuk utas dalam strim selari menggunakan forEach?
Imbas Kembali
Strim selari menggunakan ForkJoinPool. Ia berkesan untuk saluran pemprosesan yang besar, terikat CPU, tidak sensitif terhadap susunan dan tidak mempunyai keadaan. Jangan ubah keadaan yang dikongsi. Ukur prestasi sebelum membuat keputusan — pemprosesan selari sering lebih perlahan untuk data kecil.
Pelajari Java dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 104
- Pelajaran
- 374
Soalan Lazim
Adakah pelajaran “Strim Selari: Prestasi dan Perangkap” percuma?
Ya — teks penuh “Strim Selari: Prestasi dan Perangkap” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Strim Selari: Prestasi dan Perangkap”?
Dayakan strim selari, fahami kumpulan thread umum dan elakkan pepijat keadaan boleh ubah yang dikongsi. Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Java Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.
Berapa lamakah pelajaran “Strim Selari: Prestasi dan Perangkap” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?
Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- flatMap untuk Koleksi Bersarang
- Strim Selari: Prestasi dan Perangkap
- Spliterator: Pemisahan untuk Keselarian
- Strim Tanpa Had dengan iterate dan generate