0Pricing
Java Academy · บทเรียน

การสร้างสตรีมแบบขนาน

parallel() และ parallelStream()

การสร้างสตรีมแบบขนาน เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

การทำงานของสตรีมแบบ parallel

สตรีมแบบ parallel จะแบ่งข้อมูลออกเป็นส่วนย่อย ประมวลผลแต่ละส่วนด้วยหลายเธรด แล้วรวมผลลัพธ์เข้าด้วยกัน เป้าหมายคือเพิ่มอัตราการประมวลผลสำหรับงานขนาดใหญ่

import java.util.stream.IntStream;

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

parallel() กับสตรีมที่มีอยู่

การเรียกใช้ parallel() จะเปลี่ยนสตรีมแบบลำดับเดียวให้เป็นสตรีมแบบ parallel และสามารถวางไว้ที่ใดก็ได้ในลำดับการประมวลผล

import java.util.List;

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

parallelStream() บนชุดข้อมูล

Collection.parallelStream() สร้างสตรีมแบบ parallel โดยตรง เป็นทางลัดแทน stream().parallel()

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> words = List.of("a", "bb", "ccc");
        int chars = words.parallelStream()
            .mapToInt(String::length)
            .sum();
        System.out.println(chars);
    }
}

กลับเป็นแบบลำดับเดียว

sequential() เปลี่ยนสตรีมกลับเป็นการทำงานด้วยเธรดเดียว การเรียกใช้ parallel() หรือ sequential() ครั้งล่าสุดจะมีผลกับลำดับการประมวลผลทั้งหมด

import java.util.stream.IntStream;

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

การตรวจสอบ isParallel

isParallel() รายงานว่าสตรีมจะทำงานแบบ parallel หรือไม่

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        System.out.println(IntStream.range(0, 10).isParallel());
        System.out.println(IntStream.range(0, 10).parallel().isParallel());
    }
}

ผลลัพธ์เหมือนกัน การทำงานต่างกัน

สำหรับการดำเนินการที่มีสมบัติการจัดหมู่ เช่น การหาผลรวม สตรีมแบบ parallel และแบบลำดับเดียวจะคืนค่า ผลลัพธ์เดียวกัน สิ่งที่ต่างกันมีเพียงวิธีการทำงาน

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int seq = IntStream.rangeClosed(1, 50).sum();
        int par = IntStream.rangeClosed(1, 50).parallel().sum();
        System.out.println(seq == par);
    }
}

ForkJoinPool ร่วม

สตรีมแบบ parallel ใช้ ForkJoinPool.commonPool() ร่วมกัน โดยขนาดเริ่มต้นคือจำนวนหน่วยประมวลผลที่พร้อมใช้งานลบหนึ่ง

public class Main {
    public static void main(String[] args) {
        System.out.println(Runtime.getRuntime().availableProcessors());
    }
}

ไม่รับประกันลำดับของเธรด

เมื่อใช้ forEach สตรีมแบบ parallel อาจแสดงผลในลำดับใดก็ได้ เพราะแต่ละส่วนเสร็จในเวลาต่างกัน หากลำดับมีความสำคัญ ให้ใช้ forEachOrdered

import java.util.stream.IntStream;

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

การลดรวมจะรวมผลลัพธ์บางส่วน

เบื้องหลัง การลดรวมแบบ parallel จะคำนวณผลลัพธ์บางส่วนของแต่ละส่วน แล้วรวมเข้าด้วยกันด้วยตัวรวมผลลัพธ์ การดำเนินการต้องมีสมบัติการจัดหมู่จึงจะถูกต้อง

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int product = IntStream.rangeClosed(1, 6)
            .parallel()
            .reduce(1, (a, b) -> a * b);
        System.out.println(product);
    }
}

การรวบรวมแบบ parallel

ระบบตัวรวบรวมรองรับการรวบรวมแบบ parallel ด้วยการรวมโครงสร้างเก็บข้อมูลบางส่วนเข้าด้วยกัน groupingBy ทำงานได้อย่างถูกต้องในแบบ parallel

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> words = List.of("apple", "banana", "avocado", "cherry");
        Map<Character, List<String>> byFirst = words.parallelStream()
            .collect(Collectors.groupingBy(w -> w.charAt(0)));
        System.out.println(byFirst);
    }
}

สตรีมไม่ได้เร็วขึ้นทุกกรณี

การเปิดใช้การทำงานแบบ parallel ทำได้ง่าย แต่ไม่ได้ให้ประโยชน์เสมอไป ชุดข้อมูลขนาดเล็กหรือการดำเนินการที่ใช้เวลาน้อยอาจทำงานช้าลงเมื่อทำแบบ parallel เนื่องจากต้นทุนแฝงของการแบ่งและการรวม

import java.util.stream.IntStream;

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

ตรวจสอบความเข้าใจ

โดยค่าเริ่มต้น สตรีมแบบ parallel ทำงานบนกลุ่มเธรดใด?

สรุปทบทวน

คุณได้สร้างสตรีมแบบ parallel:

  • parallel() เปลี่ยนสตรีมใด ๆ ได้ ส่วน parallelStream() เป็นทางลัดสำหรับชุดข้อมูล
  • sequential() เปลี่ยนกลับเป็นแบบลำดับเดียว โดยการเรียกครั้งล่าสุดจะมีผล
  • สตรีมเหล่านี้ทำงานบน ForkJoinPool.commonPool() ที่ใช้ร่วมกัน
  • ผลลัพธ์จะตรงกับแบบลำดับเดียวสำหรับการดำเนินการที่มีสมบัติการจัดหมู่ แต่ไม่รับประกันลำดับและความเร็ว

คำถามที่พบบ่อย

บทเรียน “การสร้างสตรีมแบบขนาน” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสร้างสตรีมแบบขนาน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างสตรีมแบบขนาน”

parallel() และ parallelStream() คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การสร้างสตรีมแบบขนาน” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้างสตรีมแบบขนาน
  2. เมื่อการประมวลผลแบบขนานช่วยได้
  3. ความปลอดภัยของเธรดและผลข้างเคียง
  4. ข้อผิดพลาดที่พบบ่อย
← กลับไปที่ Java Academy