دمج Futures: allOf وanyOf
انتظر اكتمال جميع futures باستخدام allOf، وتسابق بينها باستخدام anyOf لتنفيذ منطق المهلة والبديل الاحتياطي
دمج Futures: allOf وanyOf درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
لماذا ندمج Futures؟
عندما يمكن تشغيل مهام غير متزامنة مستقلة بالتوازي، ستحتاج إلى انتظار اكتمالها جميعًا أو اكتمال أول مهمة منها قبل المتابعة. يتعامل allOf وanyOf مع كلتا الحالتين.
allOf: انتظار اكتمال جميع Futures
تعيد CompletableFuture.allOf(futures...) كائن CompletableFuture<Void> يكتمل عند اكتمال جميع futures المُدخلة. وإذا فشل أي منها، يفشل allOf أيضًا.
CompletableFuture<String> f1 = fetchUserAsync();
CompletableFuture<List<Order>> f2 = fetchOrdersAsync();
CompletableFuture<Double> f3 = fetchBalanceAsync();
CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3);
all.join(); // wait for all three
String user = f1.join();
List<Order> orders = f2.join();
Double balance = f3.join();جمع نتائج allOf
بما أن allOf يعيد Void، اجمع النتائج باستدعاء join() على كل future فردي بعد استدعاء allOf.join().
List<CompletableFuture<String>> futures = List.of(
fetchAsync("url1"), fetchAsync("url2"), fetchAsync("url3"));
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()))
.thenAccept(results -> results.forEach(System.out::println))
.join();anyOf: يفوز أول Future مكتمل
تعيد CompletableFuture.anyOf(futures...) كائن CompletableFuture<Object> يكتمل بنتيجة أول future مكتمل، بغض النظر عن نوعه.
CompletableFuture<Object> first = CompletableFuture.anyOf(
fetchFromCacheAsync(),
fetchFromDbAsync(),
fetchFromApiAsync()
);
System.out.println("Fastest result: " + first.join());anyOf كحل بديل للمهلة
نافِس عملية حسابية حقيقية بـ future خاص بالمهلة. أيّهما يكتمل أولًا يفوز — وبذلك تُطبَّق آلية مهلة دون حجب.
CompletableFuture<String> real = fetchDataAsync();
CompletableFuture<String> timeout = CompletableFuture
.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) {}
return "timeout-default";
});
String result = (String) CompletableFuture.anyOf(real, timeout).join();orTimeout (في Java 9 فأحدث)
يُكمل orTimeout(time, unit) future بالاستثناء TimeoutException إذا لم ينتهِ في الوقت المحدد. وهو أنظف من نمط anyOf مع المهلة اليدوي.
CompletableFuture<String> result = fetchDataAsync()
.orTimeout(3, TimeUnit.SECONDS)
.exceptionally(ex -> "timeout-default");
System.out.println(result.join());استدعاءات HTTP متوازية باستخدام allOf
أرسل الطلبات إلى خدمات متعددة بالتوازي، ثم ادمج النتائج. وهذا أسرع بكثير من الاستدعاءات المتسلسلة عندما تكون الخدمات مستقلة.
List<String> urls = List.of(url1, url2, url3);
List<CompletableFuture<String>> futures = urls.stream()
.map(url -> CompletableFuture.supplyAsync(() -> httpGet(url)))
.collect(Collectors.toList());
List<String> responses = CompletableFuture
.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList()))
.join();معالجة الأخطاء في allOf
إذا فشل future واحد في allOf، يفشل future المُعاد فورًا. غلّف futures الفردية باستخدام exceptionally لمنع فشل واحد من إسقاط الدفعة بأكملها.
List<CompletableFuture<String>> safe = futures.stream()
.map(f -> f.exceptionally(ex -> "ERROR: " + ex.getMessage()))
.collect(Collectors.toList());
CompletableFuture.allOf(safe.toArray(new CompletableFuture[0])).join();allOf مع أنواع مختلفة
يقبل allOf futures من أنواع مختلفة. بعد الدمج، حوّل نتيجة كل future إلى النوع المتوقع.
CompletableFuture<User> userFuture = fetchUser(id);
CompletableFuture<Config> configFuture = fetchConfig();
CompletableFuture.allOf(userFuture, configFuture).join();
User user = userFuture.join();
Config config = configFuture.join();تركيب allOf وthenApply
اربط thenApply بـ allOf لتجميع النتائج فور اكتمال جميع futures.
CompletableFuture<String> summary =
CompletableFuture.allOf(f1, f2, f3)
.thenApply(v -> "User: " + f1.join() +
", Orders: " + f2.join().size() +
", Balance: " + f3.join());
System.out.println(summary.join());اعتبارات تجمع الخيوط
يمكن تشغيل جميع futures في استدعاء allOf أو anyOf بالتزامن. تأكّد من أن تجمع الخيوط يحتوي على عدد كافٍ من الخيوط، أو استخدم الخيوط الافتراضية (في Java 21 فأحدث) لتجنّب نفاد الموارد.
// With virtual threads (Java 21+):
ExecutorService vt = Executors.newVirtualThreadPerTaskExecutor();
CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> httpGet(url), vt);انتشار الإلغاء
لا يلغي allOf أو anyOf تلقائيًا بقية futures عند اكتمال أحدها أو إلغائه. ألغِ كل future على حدة عند الحاجة.
CompletableFuture<Object> first = CompletableFuture.anyOf(f1, f2, f3);
first.thenRun(() -> Stream.of(f1, f2, f3).forEach(f -> f.cancel(true)));تحقّق سريعًا
ماذا يعيد CompletableFuture.anyOf؟
مراجعة
ينتظر allOf جميع futures (تجميع النتائج). ويأخذ anyOf النتيجة الأولى (تسابق). استخدم orTimeout للمهلات. غلّف futures الفردية باستخدام exceptionally لمنع فشل واحد من إسقاط الدفعة بأكملها.
الأسئلة الشائعة
هل درس «دمج Futures: allOf وanyOf» مجاني؟
نعم — نص درس «دمج Futures: allOf وanyOf» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «دمج Futures: allOf وanyOf»؟
انتظر اكتمال جميع futures باستخدام allOf، وتسابق بينها باستخدام anyOf لتنفيذ منطق المهلة والبديل الاحتياطي تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «دمج Futures: allOf وanyOf»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- إنشاء CompletableFutures وإكمالها
- التسلسل باستخدام thenApply وthenCompose
- دمج Futures: allOf وanyOf
- معالجة الأخطاء وخط أنابيب HTTP غير المتزامن