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

StructuredTaskScope

แยกงานย่อยและรวมผล

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

ทำความรู้จัก StructuredTaskScope

StructuredTaskScope คือส่วนติดต่อโปรแกรมประยุกต์หลักของการทำงานพร้อมกันแบบมีโครงสร้าง คุณเปิด scope, แยกงานย่อยด้วย fork, รอด้วย join แล้วจึงอ่านผลลัพธ์ของงานเหล่านั้น

นี่เป็นคุณลักษณะรุ่นทดลอง ดังนั้นให้คอมไพล์และเรียกใช้ด้วย --enable-preview

วงจรชีวิตพื้นฐาน

การใช้งานทุกครั้งมีจังหวะ 4 ขั้นตอนเหมือนกัน:

  • เปิด scope ภายในบล็อก try พร้อมการจัดการทรัพยากร
  • ใช้ fork แยกงานย่อยอย่างน้อยหนึ่งงาน โดยแต่ละงานจะคืนตัวจัดการ Subtask
  • ใช้ join เพื่อรอให้งานเสร็จ
  • อ่านผลลัพธ์ของงานย่อยแต่ละงานผ่าน get()

Fork คืนตัวจัดการ

fork(Callable) จะเริ่มงานย่อยบนเธรดเสมือนทันทีและคืนค่าเป็น Subtask คุณต้องไม่เรียก get() จนกว่า join() จะคืนค่า

ตัวอย่างที่สมบูรณ์

ในที่นี้ งานย่อยสองงานทำงานพร้อมกัน งานทั้งสองต้องเสร็จก่อนที่เราจะอ่านผลลัพธ์ ตัวอย่างนี้ใช้ ShutdownOnFailure ซึ่งเป็นนโยบายที่มีมาให้ในระบบ

import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            var name = scope.fork(() -> "Grace");
            var count = scope.fork(() -> 3);
            scope.join();
            scope.throwIfFailed();
            System.out.println(name.get() + " placed " + count.get() + " orders");
        }
    }
}

ใช้ join แล้วจึงอ่าน

ลำดับการเรียกมีกฎที่เคร่งครัด: fork แล้วจึง join จากนั้นจึง get การเรียก get() กับงานย่อยก่อนที่ join() จะเสร็จ จะทำให้เกิด IllegalStateException

กฎนี้ทำให้อายุการใช้งานยังคงมีโครงสร้าง

สถานะของงานย่อย

หลังจาก join() งานย่อยแต่ละงานจะแจ้ง state() ดังนี้:

  • SUCCESS พร้อมผลลัพธ์จาก get()
  • FAILED พร้อมข้อยกเว้นจาก exception()
  • UNAVAILABLE หากงานนั้นยังไม่เสร็จสมบูรณ์

งานย่อยจำนวนมาก

คุณสามารถใช้ fork แยกงานย่อยได้มากเท่าที่ต้องการ โดยแต่ละงานจะได้รับเธรดเสมือนของตนเอง นี่คือวิธีแยกการเรียกอิสระหลายรายการออกไปทำงานพร้อมกัน

import java.util.*;
import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            List<StructuredTaskScope.Subtask<Integer>> tasks = new ArrayList<>();
            for (int i = 1; i <= 5; i++) {
                final int n = i;
                tasks.add(scope.fork(() -> n * n));
            }
            scope.join();
            scope.throwIfFailed();
            int total = tasks.stream().mapToInt(StructuredTaskScope.Subtask::get).sum();
            System.out.println("Sum of squares 1..5 = " + total);
        }
    }
}

Scope เป็นเจ้าของเธรด

scope เป็น AutoCloseable เมื่อบล็อก try สิ้นสุด close() จะรับรองว่าเธรดของงานย่อยทุกงานสิ้นสุดแล้ว จะไม่มีการรั่วไหลเกิดขึ้น

นี่คือเหตุผลที่คุณต้องใช้ scope ภายในบล็อก try พร้อมการจัดการทรัพยากรเสมอ

นโยบายที่มีมาให้

JDK มีนโยบายการหยุดทำงานที่พร้อมใช้งานมาให้สองแบบ:

  • ShutdownOnFailure: ยกเลิกงานที่เหลือหากงานย่อยใดงานหนึ่งล้มเหลว
  • ShutdownOnSuccess: ยกเลิกงานที่เหลือทันทีที่งานหนึ่งงานใดสำเร็จ

คุณยังสามารถสร้างคลาสย่อยของ StructuredTaskScope เพื่อใช้ตรรกะที่กำหนดเองได้

เธรดเดียวเป็นผู้เรียก join

เฉพาะเธรดที่เปิด scope เท่านั้นที่สามารถแยกงานเข้าไปใน scope และเรียก join ได้ งานย่อยจะถูกจำกัดให้อยู่ใน scope ที่เป็นเจ้าของ ซึ่งช่วยให้ต้นไม้มีรูปแบบถูกต้อง

ตัวเลือกสำหรับคอมไพล์และเรียกใช้

เนื่องจากส่วนติดต่อโปรแกรมประยุกต์นี้เป็นรุ่นทดลอง ให้สร้างโปรแกรมด้วย:

  • javac --release 21 --enable-preview Main.java
  • java --enable-preview Main

หากไม่ใส่ตัวเลือกนี้ คุณจะพบข้อผิดพลาดระหว่างการคอมไพล์หรือขณะเรียกใช้

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทบทวนลำดับการเรียกที่จำเป็น

สรุปทบทวน

คุณได้เรียนรู้ส่วนติดต่อโปรแกรมประยุกต์ StructuredTaskScope:

  • เปิดในบล็อก try พร้อมการจัดการทรัพยากร จากนั้นใช้ fork, join แล้วจึง get
  • งานย่อยแต่ละงานทำงานบนเธรดเสมือนของตนเอง
  • scope รับรองว่างานย่อยทั้งหมดจะสิ้นสุดก่อนการปิด
  • ต้องใช้ --enable-preview

ถัดไป: นโยบายหยุดทำงานเมื่อล้มเหลวและหยุดทำงานเมื่อสำเร็จในรายละเอียด

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

บทเรียน “StructuredTaskScope” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “StructuredTaskScope”

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

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

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

บทเรียน “StructuredTaskScope” ใช้เวลานานแค่ไหน

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

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

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

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

  1. โมเดลการทำงานพร้อมกันแบบมีโครงสร้าง
  2. StructuredTaskScope
  3. การปิดเมื่อเกิดความล้มเหลวและเมื่อสำเร็จ
  4. การจัดการข้อผิดพลาดและการยกเลิก
← กลับไปที่ Java Academy