الإيقاف عند الفشل والنجاح
تنسيق نتائج المهام
الإيقاف عند الفشل والنجاح درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
نَمطان شائعان
تندرج معظم عمليات توزيع العمل المتزامن ضمن شكلين:
- يجب أن تنجح جميعها: إذا فشلت إحداها، فتخلَّ عن البقية. استخدم
ShutdownOnFailure. - الفائز هو الأول: بمجرد نجاح إحداها، ألغِ البقية. استخدم
ShutdownOnSuccess.
يوفّر JDK النمطين مباشرة.
فكرة ShutdownOnFailure
تُستخدم ShutdownOnFailure للمهام التي يجب أن تنجح جميعها، مثل جمع ملف المستخدم وطلباته معًا.
إذا طرحت إحدى المهام الفرعية استثناءً، يلغي النطاق المهام الأخرى حتى لا تهدر جهدًا عليها.
مثال على ShutdownOnFailure
بعد join()، تستدعي throwIfFailed()، التي تعيد طرح أول فشل، إن وُجد، بعد تغليفه في ExecutionException.
import java.util.concurrent.StructuredTaskScope;
public class Main {
public static void main(String[] args) throws Exception {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var a = scope.fork(() -> fetch("profile"));
var b = scope.fork(() -> fetch("orders"));
scope.join();
scope.throwIfFailed();
System.out.println(a.get() + " + " + b.get());
}
}
static String fetch(String what) {
return what + "-ok";
}
}ما الذي يفعله throwIfFailed
تفحص throwIfFailed() المهام الفرعية. فإذا نجحت جميعها، لم تفعل شيئًا. وإذا فشلت أي منها، طرحت استثناءً يغلّف الاستثناء الأصلي.
يمكنك أيضًا تمرير دالة لتحويل السبب إلى نوع استثناء مخصص.
فكرة ShutdownOnSuccess
تُستخدم ShutdownOnSuccess للتكرار أو التسابق: استعلم من عدة نسخ متطابقة وخذ الإجابة التي تصل أولًا.
في اللحظة التي تنجح فيها إحدى المهام الفرعية، يلغي النطاق المهام الأخرى ويخزّن النتيجة الفائزة.
مثال على ShutdownOnSuccess
تسترجع القيمة الفائزة باستخدام result(). ويُطرح استثناء إذا لم تنجح أي مهمة فرعية.
import java.util.concurrent.StructuredTaskScope;
public class Main {
public static void main(String[] args) throws Exception {
try (var scope = new StructuredTaskScope.ShutdownOnSuccess<String>()) {
scope.fork(() -> queryMirror("eu"));
scope.fork(() -> queryMirror("us"));
scope.join();
System.out.println("Fastest answer: " + scope.result());
}
}
static String queryMirror(String region) {
return region + "-data";
}
}result في مقابل get
لاحظ الفرق:
ShutdownOnFailure: اقرأ كل مهمة فرعية باستخدامget()الخاص بهاShutdownOnSuccess: اقرأ الفائز الوحيد باستخدامresult()الخاص بالنطاق
الإلغاء تعاوني
عندما يُوقِف النطاق عمله، فإنه يقاطع خيوط المهام الفرعية المتبقية. وتتحقق المهام المصممة جيدًا من المقاطعة وتتوقف بسرعة.
تستجيب الاستدعاءات الحاجزة في المكتبة القياسية للمقاطعة تلقائيًا في الغالب.
join مع مهلة
تدعم السياستان حدًا زمنيًا نهائيًا. إذ ينتظر استدعاء joinUntil(Instant) حتى وقت محدد فقط، ثم يطرح TimeoutException ويوقف النطاق.
اختيار السياسة
اطرح على نفسك سؤالًا واحدًا: هل أحتاج إلى جميع النتائج أم إلى النتيجة الأولى فقط؟
- جميع النتائج مع التوقف السريع عند الخطأ:
ShutdownOnFailure - أي نتيجة واحدة، والفوز للأسرع:
ShutdownOnSuccess
أما في الحالات الأخرى، فأنشئ فئة فرعية من StructuredTaskScope.
السياسات المخصصة
يمكنك توسيع StructuredTaskScope وتجاوز handleComplete(Subtask) لتنفيذ قواعد مخصصة، مثل جمع أول N نجاحات أو الإيقاف بعد بلوغ عدد محدد من حالات الفشل.
تحقق سريع
طابق السيناريو مع السياسة المناسبة.
مراجعة
تعلّمت سياستي الإيقاف المضمّنتين:
ShutdownOnFailure+throwIfFailed+getلكل مهمة فرعية عندما يجب أن تنجح جميع المهامShutdownOnSuccess+resultعندما يفوز الأول- يقاطع الإيقاف المهام الفرعية المتبقية بطريقة تعاونية
- يضيف
joinUntilحدودًا زمنية نهائية، بينما تضيف الفئات الفرعية قواعد مخصصة
التالي: معالجة الأخطاء والإلغاء بالتفصيل.
الأسئلة الشائعة
هل درس «الإيقاف عند الفشل والنجاح» مجاني؟
نعم — نص درس «الإيقاف عند الفشل والنجاح» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «الإيقاف عند الفشل والنجاح»؟
تنسيق نتائج المهام تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «الإيقاف عند الفشل والنجاح»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- نموذج التزامن المنظّم
- StructuredTaskScope
- الإيقاف عند الفشل والنجاح
- معالجة الأخطاء والإلغاء