0Pricing
Java Academy · درس

StructuredTaskScope

تفريع المهام الفرعية وضمّها

StructuredTaskScope درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

تعرّف إلى StructuredTaskScope

تُعد StructuredTaskScope واجهة برمجة التطبيقات الأساسية للتزامن المُنظَّم. تفتح نطاقًا، ثم تنفّذ fork للمهام الفرعية، وتنفّذ join للانتظار حتى تكتمل، ثم تقرأ نتائجها.

هذه ميزة تجريبية، لذا يجب الترجمة والتشغيل باستخدام --enable-preview.

دورة الحياة الأساسية

يتبع كل استخدام الإيقاع نفسه المؤلف من أربع خطوات:

  • افتح النطاق داخل كتلة try-with-resources
  • نفّذ 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()، تعرض كل Subtask حالة عبر 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);
        }
    }
}

النطاق يملك الخيوط

النطاق هو AutoCloseable. وعند انتهاء كتلة try، يضمن close() انتهاء كل خيط من خيوط المهام الفرعية. لذلك لا يمكن حدوث تسرّبات.

ولهذا تستخدمه دائمًا داخل try-with-resources.

السياسات المضمّنة

يوفّر JDK سياستين جاهزتين للإيقاف:

  • ShutdownOnFailure: ألغِ بقية المهام إذا فشلت أي مهمة فرعية
  • ShutdownOnSuccess: ألغِ بقية المهام بمجرد نجاح إحداها

يمكنك أيضًا إنشاء فئة فرعية من StructuredTaskScope لتنفيذ منطق مخصص.

ينفّذ الخيط نفسه join

لا يجوز تنفيذ fork أو استدعاء join في النطاق إلا من الخيط الذي فتحه. وتبقى المهام الفرعية محصورة في النطاق المالِك لها، مما يحافظ على سلامة بنية الشجرة.

خيارات الترجمة والتشغيل

بما أن واجهة البرمجة تطبيقية تجريبية، فأنشئ البناء باستخدام:

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

من دون الخيار، ستحصل على خطأ في الترجمة أو وقت التشغيل.

تحقق سريع

تذكّر ترتيب الاستدعاءات الإلزامي.

مراجعة

تعلّمت واجهة برمجة التطبيقات StructuredTaskScope:

  • افتح النطاق داخل try-with-resources، ثم نفّذ fork وjoin ثم get
  • تعمل كل مهمة فرعية على خيط افتراضي خاص بها
  • يضمن النطاق انتهاء جميع المهام الفرعية قبل إغلاقه
  • يتطلب --enable-preview

التالي: سياستا الإيقاف عند الفشل والإيقاف عند النجاح بالتفصيل.

الأسئلة الشائعة

هل درس «StructuredTaskScope» مجاني؟

نعم — نص درس «StructuredTaskScope» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «StructuredTaskScope»؟

تفريع المهام الفرعية وضمّها تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «StructuredTaskScope»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. نموذج التزامن المنظّم
  2. StructuredTaskScope
  3. الإيقاف عند الفشل والنجاح
  4. معالجة الأخطاء والإلغاء
← العودة إلى Java Academy