0Pricing
Java Academy · Pelajaran

Kesalahan Umum

Pengurutan, boxing, dan kumpulan thread umum.

Kesalahan Umum adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.

parallel Bukan Jaminan Kecepatan

Menambahkan parallel() dapat membuat kode lebih lambat, bukan lebih cepat. Pelajaran ini membahas jebakan umum agar Anda dapat menghindarinya.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long sum = IntStream.rangeClosed(1, 1_000_000).parallel()
            .asLongStream().sum();
        System.out.println(sum);
    }
}

Jebakan: Beban Tambahan untuk Menjaga Urutan

Operasi yang mempertahankan urutan seperti forEachOrdered atau limit memaksa koordinasi di antara utas, sehingga mengurangi manfaat paralelisme.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.rangeClosed(1, 5).parallel()
            .forEachOrdered(System.out::println);
    }
}

unordered Dapat Membantu

Jika urutan tidak penting, memanggil unordered() memungkinkan lingkungan runtime melewati pekerjaan pengurutan dan melakukan paralelisasi dengan lebih leluasa.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long count = IntStream.rangeClosed(1, 1_000_000).parallel()
            .unordered()
            .filter(n -> n % 5 == 0)
            .count();
        System.out.println(count);
    }
}

Jebakan: Pembungkusan Tersembunyi

Menggunakan Stream<Integer> secara parallel melipatgandakan biaya pembungkusan di antara utas. Utamakan aliran primitif untuk pekerjaan numerik secara parallel.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long sum = IntStream.rangeClosed(1, 1_000_000).parallel().asLongStream().sum();
        System.out.println(sum);
    }
}

Jebakan: Kumpulan Umum yang Dipakai Bersama

Semua aliran parallel berbagi satu ForkJoinPool.commonPool(). Tugas parallel yang berlangsung lama dapat membuat tugas lain dalam JVM yang sama kehabisan sumber daya, termasuk bagian lain dari aplikasi Anda.

import java.util.concurrent.ForkJoinPool;

public class Main {
    public static void main(String[] args) {
        System.out.println(ForkJoinPool.commonPool().getParallelism());
    }
}

Mengisolasi Pekerjaan dalam Kumpulan Khusus

Untuk menjaga pekerjaan berat agar tidak menggunakan kumpulan umum, kirimkan aliran parallel di dalam ForkJoinPool Anda sendiri.

import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) throws Exception {
        ForkJoinPool pool = new ForkJoinPool(2);
        long sum = pool.submit(() ->
            IntStream.rangeClosed(1, 1_000_000).parallel().asLongStream().sum()
        ).get();
        pool.shutdown();
        System.out.println(sum);
    }
}

Jebakan: Sumber yang Sulit Dibagi

LinkedList, Stream.iterate, dan BufferedReader.lines sulit dibagi. Memparalelkan sumber-sumber tersebut sering kali hanya menghasilkan sedikit manfaat atau bahkan kerugian.

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        long n = Stream.iterate(1, x -> x + 1)
            .limit(100_000)
            .parallel()
            .filter(x -> x % 2 == 0)
            .count();
        System.out.println(n);
    }
}

Jebakan: Lambda Berstatus

Lambda yang membaca atau menulis status eksternal berperilaku nondeterministik secara parallel. Jaga agar lambda tidak memiliki status untuk memperoleh hasil yang konsisten.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int sum = IntStream.rangeClosed(1, 100).parallel()
            .map(n -> n + 1)
            .sum();
        System.out.println(sum);
    }
}

Jebakan: findFirst dibandingkan dengan findAny

findFirst harus menghormati urutan, sehingga menambah beban tambahan secara parallel. Jika elemen mana pun yang cocok sudah cukup, gunakan findAny.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int found = IntStream.rangeClosed(1, 1_000_000).parallel()
            .filter(n -> n % 99991 == 0)
            .findAny()
            .getAsInt();
        System.out.println(found);
    }
}

Jebakan: Operasi Murah pada Data Kecil

Untuk koleksi yang sangat kecil atau pekerjaan sepele, beban tambahan untuk membagi dan menggabungkan data jauh lebih besar daripada manfaat apa pun. Tetap gunakan pemrosesan berurutan.

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> small = List.of(1, 2, 3, 4);
        int sum = small.stream().mapToInt(Integer::intValue).sum();
        System.out.println(sum);
    }
}

Jebakan: Penggabungan Mahal dalam Kolektor

Kolektor dengan langkah penggabungan yang mahal, seperti saat membangun struktur terurut yang besar, dapat menghapus manfaat paralelisme. Akumulasi sederhana dapat digabungkan dengan murah.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long total = IntStream.rangeClosed(1, 1_000_000).parallel()
            .mapToLong(n -> n)
            .sum();
        System.out.println(total);
    }
}

Pemeriksaan Singkat

Mengapa findFirst dapat lebih lambat daripada findAny pada aliran parallel?

Rangkuman

Anda telah mempelajari jebakan umum aliran parallel:

  • Penjagaan urutan (forEachOrdered, limit, findFirst) menambah biaya koordinasi; gunakan unordered atau findAny jika memungkinkan.
  • Pembungkusan melipatgandakan biaya; utamakan aliran primitif.
  • Kumpulan umum yang dipakai bersama dapat kehabisan sumber daya; isolasi pekerjaan berat dalam ForkJoinPool khusus.
  • Sumber yang sulit dibagi, data kecil, dan penggabungan mahal semuanya mengurangi manfaat paralelisme.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Kesalahan Umum” gratis?

Ya — teks lengkap “Kesalahan Umum” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Kesalahan Umum”?

Pengurutan, boxing, dan kumpulan thread umum. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Java Academy?

Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Kesalahan Umum” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Membuat Stream Paralel
  2. Kapan Paralelisme Membantu
  3. Keamanan Thread dan Efek Samping
  4. Kesalahan Umum
← Kembali ke Java Academy