Java CompletableFuture allOf() & anyOf() Sinhala Guide - Async Programming

Mastering Parallel Async Tasks with Java CompletableFuture | Sinhala Guide
Mastering Parallel Async Tasks with Java CompletableFuture | Sinhala Guide
කෝමත් programming කරනකොට අපිට ගොඩක් වෙලාවට එකපාර tasks කිහිපයක් run කරන්න වෙනවා නේද? උදාහරණයක් විදිහට, web application එකකදී user කෙනෙක්ගේ profile details, order history, notifications වගේ data chunks කිහිපයක් එකපාර fetch කරන්න ඕනේ වෙන්න පුළුවන්. මේ හැම task එකක්ම එක task එකක් ඉවර වෙනකල් බලන් ඉඳලා ඊළඟ එක පටන් ගන්නවා නම්, ඒක අපේ application එකේ performance එකට ලොකු බලපෑමක් කරනවා. User experience එකත් හොඳටම අඩු වෙනවා, මොකද හැමදේම load වෙන්න වැඩි වෙලාවක් යන නිසා.
අන්න ඒ වගේ තත්ත්වයකදී තමයි Asynchronous Programming කියන concept එක අපිට ලොකු අතහිතක් දෙන්නේ. Java 8 වලින් පස්සේ ආපු CompletableFuture
කියන්නේ මේ වගේ asynchronous operations පහසුවෙන් handle කරන්න තියෙන නියම tool එකක්. ඒක සාමාන්ය Future
එකේ තිබ්බ limitations ගොඩක් අයින් කරලා, chaining, combining, error handling වගේ දේවල් කරන්න පුළුවන් විදියට හදලා තියෙනවා.
මේ tutorial එකෙන් අපි බලමු CompletableFuture
එකෙන් tasks කිහිපයක් එකට handle කරන්නේ කොහොමද කියලා. විශේෂයෙන්ම CompletableFuture.allOf()
සහ CompletableFuture.anyOf()
කියන powerful methods දෙක භාවිතයෙන් අපේ code එක තව දුරටත් efficent සහ responsive කරගන්නේ කොහොමද කියලා අපි සවිස්තරාත්මකව කතා කරනවා. Practical code examples හරහා මේ concepts පැහැදිලි කරන නිසා, ඔයාලට මේවා ඔයාලගේ project වලට direct apply කරන්න පුළුවන් වෙයි!
CompletableFuture කියන්නේ මොකක්ද? (What is CompletableFuture?)
java.util.concurrent.CompletableFuture
කියන්නේ Java 8 වලට add කරපු class එකක්. මේක Future
interface එකේ implementation එකක්. ඒත් සාමාන්ය Future
එකට වඩා advanced functionality මේකේ තියෙනවා. CompletableFuture
එකකදී අපිට පහත දේවල් කරන්න පුළුවන්:
- සැපයුම්කරුවෙකු ලෙස ක්රියා කිරීම (Acting as a Supplier): අපිට value එකක් අරන් එන task එකක් run කරන්න පුළුවන්.
- තවත් task එකක් දාමය (Chaining another Task): එක task එකක් ඉවර වුන ගමන් ඊළඟ task එක run කරන්න පුළුවන්.
- ප්රතිඵල පරිභෝජනය (Consuming Results): task එකක result එකක් ආවට පස්සේ ඒක process කරන්න පුළුවන්.
- දෝෂ හසුරුවීම (Error Handling): task එකක් fail වුනොත් ඒක catch කරලා handle කරන්න පුළුවන්.
- බහු Future එකට එකතු කිරීම (Combining Multiple Futures): මේක තමයි අපේ මේ tutorial එකේ ප්රධානම focus එක. Futures කිහිපයක ප්රතිඵල එකට join කරගන්න හෝ පළවෙනියට එන ප්රතිඵලය ගන්න පුළුවන්.
සරලවම කියනවා නම්, CompletableFuture
එකක් කියන්නේ අනාගතයේදී (in the future) result එකක් දෙන්න බලාපොරොත්තු වෙන asynchronous computation එකක් නියෝජනය කරන object එකක්. මේක non-blocking operation එකක්. ඒ කියන්නේ main thread එක මේ task එක ඉවර වෙනකල් බලාගෙන ඉන්නේ නැහැ. ඒක ඊළඟ task එකට යනවා.
allOf()
භාවිතයෙන් සියලු Futures සම්පූර්ණ කිරීම (Completing All Futures with allOf())
හිතන්න, ඔයාලට tasks කිහිපයක් තියෙනවා. ඒ හැම task එකකම result එක අපේ application එකට වැදගත්. ඒ හැම task එකක්ම සාර්ථකව ඉවර වෙනකල් අපිට ඉන්න සිද්ධ වෙනවා. මේ වගේ අවස්ථාවකදී CompletableFuture.allOf()
කියන method එක අපිට ලොකු උදව්වක් වෙනවා.
CompletableFuture.allOf(CompletableFuture... cfs)
method එකට CompletableFuture
objects කිහිපයක් parameters විදිහට දෙන්න පුළුවන්. මේ method එකෙන් CompletableFuture<Void>
එකක් return කරනවා. මේ return කරන CompletableFuture<Void>
එක සම්පූර්ණ වෙන්නේ, parameters විදිහට දුන්නු අනිත් CompletableFuture
හැම එකක්ම සම්පූර්ණ වුනාට පස්සේ විතරයි. එතකොට අපිට විශ්වාසයෙන් යුතුව හැම task එකකම result එක ගන්න පුළුවන්.
allOf()
ක්රියා කරන ආකාරය:
- සියලු Futures සම්පූර්ණ වන තෙක් රැඳී සිටීම:
allOf()
මගින් ලබා දෙනCompletableFuture
එක සම්පූර්ණ වන්නේ, ඔබ ලබා දෙන සියලුCompletableFuture
tasks සාර්ථකව අවසන් වූ පසුවයි. - ප්රතිඵල ලබා ගැනීම:
allOf()
මගින්CompletableFuture<Void>
එකක් return කරන නිසා, තනි ප්රතිඵලයක් ගණනය කිරීමක් සිදු වෙන්නේ නැහැ. ඒ වෙනුවට,allOf()
එක සම්පූර්ණ වූ පසු, ඔබට තනි තනිCompletableFuture
objects වලget()
හෝjoin()
method එක භාවිත කරලා ඒවායේ ප්රතිඵල ලබා ගන්න පුළුවන්. - දෝෂ හසුරුවීම: දී ඇති ඕනෑම
CompletableFuture
එකක් fail වුවහොත්,allOf()
එකෙන් return කරනCompletableFuture
එකත් Exception එකක් සමඟ complete වෙනවා.
ප්රායෝගික උදාහරණයක්: User Data සහ Order History එකට ලබා ගැනීම
දැන් අපි බලමු real-world scenario එකකදී මේක කොහොමද use කරන්නේ කියලා. හිතන්න, අපිට user කෙනෙක්ගේ data (නම, email) සහ එයාගේ order history එක database එකෙන් separate calls දෙකකින් ගන්න ඕනේ කියලා. මේ calls දෙකම එකපාර run කරලා, දෙකේම results ආවට පස්සේ ඒ දෙක එකට display කරන්න ඕනේ.
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.Random;
public class CompletableFutureAllOfExample {
// User data fetch කරන method එකක්
public static CompletableFuture<String> fetchUserData(String userId) {
return CompletableFuture.supplyAsync(() -> {
try {
// Network latency simulate කරමු
TimeUnit.SECONDS.sleep(new Random().nextInt(3) + 1); // 1-3 seconds
if (userId.equals("user123")) {
return "User Data for " + userId + ": Name=Kamal, [email protected]";
} else {
throw new RuntimeException("User not found: " + userId);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Failed to fetch user data for " + userId, e);
}
});
}
// Order history fetch කරන method එකක්
public static CompletableFuture<String> fetchOrderHistory(String userId) {
return CompletableFuture.supplyAsync(() -> {
try {
// Network latency simulate කරමු
TimeUnit.SECONDS.sleep(new Random().nextInt(4) + 1); // 1-4 seconds
if (userId.equals("user123")) {
return "Order History for " + userId + ": OrderID=101, Item=Laptop; OrderID=102, Item=Mouse";
} else {
throw new RuntimeException("Orders not found for: " + userId);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Failed to fetch order history for " + userId, e);
}
});
}
// Shipping address fetch කරන තවත් task එකක්
public static CompletableFuture<String> fetchShippingAddress(String userId) {
return CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(2) + 1); // 1-2 seconds
return "Shipping Address for " + userId + ": 123, Main Street, Colombo";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Failed to fetch address for " + userId, e);
}
});
}
public static void main(String[] args) {
String userId = "user123";
System.out.println("Starting allOf() example for " + userId + "...");
long startTime = System.currentTimeMillis();
// Futures 3ක් define කරමු
CompletableFuture<String> userDataFuture = fetchUserData(userId);
CompletableFuture<String> orderHistoryFuture = fetchOrderHistory(userId);
CompletableFuture<String> shippingAddressFuture = fetchShippingAddress(userId);
// Futures 3ම allOf() එකට දෙමු
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
userDataFuture,
orderHistoryFuture,
shippingAddressFuture
);
// හැම future එකක්ම complete වුනාට පස්සේ results process කරමු
allFutures.thenRun(() -> {
try {
String userData = userDataFuture.get(); // result එක ලබාගන්නවා
String orderHistory = orderHistoryFuture.get(); // result එක ලබාගන්නවා
String shippingAddress = shippingAddressFuture.get(); // result එක ලබාගන්නවා
System.out.println("\n--- All Data Retrieved Successfully ---");
System.out.println(userData);
System.out.println(orderHistory);
System.out.println(shippingAddress);
} catch (InterruptedException | ExecutionException e) {
System.err.println("Error processing combined futures: " + e.getMessage());
} finally {
long endTime = System.currentTimeMillis();
System.out.println("All futures completed in " + (endTime - startTime) + " ms.");
}
}).exceptionally(ex -> { // allOf chain එකේදී exception එකක් ආවොත් handle කරන්න
System.err.println("An error occurred in allOf chain: " + ex.getMessage());
return null;
}).join(); // අවසාන consumer එකත් complete වෙනකල් main thread එක block කරනවා.
}
}
මේ code එක run කරාම ඔයාලට පේනවා ඇති, tasks 3ම එකපාර run වෙලා, වැඩිම කාලයක් ගත්තු task එකේ වෙලාවට සාපේක්ෂව මුළු operation එකම complete වෙනවා. හිතාගන්න පුළුවන් නේද, මේක අපේ application එකේ performance එකට කොච්චර හොඳ බලපෑමක් කරනවද කියලා?
allOf()
භාවිතයේදී මතක තබා ගත යුතු දේවල්:
allOf()
එකෙන් return කරන්නේCompletableFuture<Void>
එකක්. ඒ කියන්නේ ඒකේ තනි result එකක් නැහැ. Individual results ගන්න ඕන නම්,allOf()
එක complete වුනාට පස්සේ, original futures වලget()
හෝjoin()
method call කරන්න ඕනේ.allOf()
එකට දීපු ඕනෑමCompletableFuture
එකක් exception එකක් throw කරොත්,allOf()
එකෙනුත් exception එකක් throw වෙනවා. ඒ නිසා error handling ගැන හොඳට අවධානය යොමු කරන්න ඕනේ.
anyOf()
භාවිතයෙන් ඕනෑම Future එකක් සම්පූර්ණ කිරීම (Completing Any Future with anyOf())
සමහර වෙලාවට අපිට tasks කිහිපයක් තියෙනවා, ඒත් අපිට ඕනේ ඒ tasks වලින් මොනවා හරි එකක් සාර්ථකව ඉවර වුනොත් ඒකේ result එක ගන්න. උදාහරණයක් විදිහට, එකම data set එක different services 3-4කින් ගන්න පුළුවන් වෙන්න පුළුවන්. ඒ services වලින් මොනවා හරි එකකින් data ආපු ගමන්, අපිට ඒ data එක use කරලා ඊළඟ වැඩේට යන්න පුළුවන්. මේ වගේ scenarios වලදී CompletableFuture.anyOf()
කියන method එක අපිට ලොකු උදව්වක් වෙනවා.
CompletableFuture.anyOf(CompletableFuture... cfs)
method එකටත් CompletableFuture
objects කිහිපයක් parameters විදිහට දෙන්න පුළුවන්. මේ method එකෙන් CompletableFuture<Object>
එකක් return කරනවා. මේ return කරන CompletableFuture<Object>
එක සම්පූර්ණ වෙන්නේ, parameters විදිහට දුන්නු අනිත් CompletableFuture
හැම එකක්ම සම්පූර්ණ වුනාට පස්සේ නෙවෙයි, ඒ Futures වලින් පළවෙනියට සම්පූර්ණ වෙන Future එක සම්පූර්ණ වුනාට පස්සේ. මේක හරිම useful feature එකක්.
anyOf()
ක්රියා කරන ආකාරය:
- පළමුව සම්පූර්ණ වන Future එක හසුරුවයි:
anyOf()
මගින් ලබා දෙනCompletableFuture
එක සම්පූර්ණ වන්නේ, ඔබ ලබා දෙනCompletableFuture
tasks අතරින් පළමුව සාර්ථකව අවසන් වන task එකේ ප්රතිඵලය සමඟයි. - ප්රතිඵල ලබා ගැනීම:
anyOf()
මගින්CompletableFuture<Object>
එකක් return කරන නිසා, ඔබට සෘජුවම එම ප්රතිඵලය ලබා ගැනීමට පුළුවන්. Return වන type එකObject
නිසා, cast කිරීමක් අවශ්ය විය හැක. - දෝෂ හසුරුවීම: දී ඇති සියලු
CompletableFuture
එකින් එක fail වුවහොත් පමණක්,anyOf()
එකෙන් return කරනCompletableFuture
එකත් Exception එකක් සමඟ complete වෙනවා. යම් කිසි Future එකක් සාර්ථකව අවසන් වුවහොත්, එහි ප්රතිඵලය ලබා දෙනු ඇත, අනෙක් Future වල දෝෂ තිබුණද.
ප්රායෝගික උදාහරණයක්: Fastest Service Response ලබා ගැනීම
හිතන්න, ඔයාලට data එකක් ගන්න පුළුවන් services තුනක් තියෙනවා (Service A, Service B, Service C). මේ services තුනේම response times වෙනස් වෙන්න පුළුවන්. අපිට ඕනේ මේ තුනෙන් මොන service එකෙන් හරි ඉක්මනටම data ආපු ගමන් ඒක use කරන්න. අනිත් services වලට මොනවා වුනත් අපිට ප්රශ්නයක් නැහැ, මොකද අපිට අවශ්ය data එක දැනටමත් ඇවිත්.
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.Random;
public class CompletableFutureAnyOfExample {
// Service A එකෙන් data fetch කරන method එකක්
public static CompletableFuture<String> fetchDataFromServiceA() {
return CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(4) + 2); // 2-5 seconds
System.out.println("Service A completed.");
return "Data from Service A: Fast and Reliable!";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return "Service A interrupted.";
}
});
}
// Service B එකෙන් data fetch කරන method එකක්
public static CompletableFuture<String> fetchDataFromServiceB() {
return CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(3) + 1); // 1-3 seconds
System.out.println("Service B completed.");
return "Data from Service B: Quick Response!";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return "Service B interrupted.";
}
});
}
// Service C එකෙන් data fetch කරන method එකක් (සමහරවිට fail වෙන්නත් පුළුවන්)
public static CompletableFuture<String> fetchDataFromServiceC() {
return CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(5) + 3); // 3-7 seconds
// සමහර වෙලාවට error එකක් simulate කරමු
if (new Random().nextBoolean()) {
throw new RuntimeException("Service C failed to respond!");
}
System.out.println("Service C completed.");
return "Data from Service C: Maybe a bit slow!";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return "Service C interrupted.";
} catch (RuntimeException e) {
System.err.println("Service C failed with: " + e.getMessage());
throw e; // Exception එක propagate කරනවා
}
});
}
public static void main(String[] args) {
System.out.println("\nStarting anyOf() example...");
long startTime = System.currentTimeMillis();
// Futures 3ක් define කරමු
CompletableFuture<String> futureA = fetchDataFromServiceA();
CompletableFuture<String> futureB = fetchDataFromServiceB();
CompletableFuture<String> futureC = fetchDataFromServiceC();
// Futures 3ම anyOf() එකට දෙමු
CompletableFuture<Object> anyOneFuture = CompletableFuture.anyOf(futureA, futureB, futureC);
anyOneFuture.thenAccept(result -> {
System.out.println("\n--- First Service Responded Successfully ---");
System.out.println("Received: " + result);
}).exceptionally(ex -> {
// හැම service එකක්ම fail වුනොත් මේ exception block එක run වෙනවා
System.err.println("An error occurred in anyOf chain (all services might have failed or the first one failed): " + ex.getMessage());
return null;
}).join();
long endTime = System.currentTimeMillis();
System.out.println("anyOf() example completed in " + (endTime - startTime) + " ms.");
}
}
මේ code එක run කරාම ඔයාලට පේනවා ඇති, services තුනෙන් මොකක් හරි එකක් මුලින්ම result එකක් දෙනවා. ඒක තමයි anyOf()
එකෙන් return වෙන්නේ. මේක අපේ application එකේ responsiveness එකට direct impact කරනවා.
anyOf()
භාවිතයේදී මතක තබා ගත යුතු දේවල්:
anyOf()
එකෙන් return කරන්නේCompletableFuture<Object>
එකක්. මොකද මොන Future එකෙන් result එක එයිද කියලා කලින්ම කියන්න බැරි නිසා. ඒ නිසා result එක ගන්නකොට අදාළ type එකට cast කරන්න සිද්ධ වෙනවා.- සියලුම Futures fail වුනොත් විතරයි
anyOf()
එකෙන් exception එකක් throw කරන්නේ. එක Future එකක් හරි සාර්ථක වුනොත් ඒකේ result එක return කරනවා.
ප්රායෝගික උපදෙස් සහ හොඳම භාවිතයන් (Practical Tips and Best Practices)
CompletableFuture
එක්ක වැඩ කරනකොට ඔයාලගේ code එක තවත් robust සහ maintainable කරගන්න පුළුවන් tricks කිහිපයක් මෙන්න:
1. දෝෂ හසුරුවීම (Error Handling)
Asynchronous operations වලදී errors handle කරන එක ගොඩක් වැදගත්. CompletableFuture
එකේ errors handle කරන්න methods කිහිපයක් තියෙනවා:
exceptionally(Function<Throwable, ? extends T> fn)
: මේක stream එකේcatch
block එකක් වගේ වැඩ කරනවා. Future එකක් fail වුනොත්, default value එකක් return කරන්න හෝ recovery logic එකක් implement කරන්න පුළුවන්.handle(BiFunction<? super T, Throwable, ? extends U> fn)
: මේකෙන් result එකයි, exception එකයි දෙකම handle කරන්න පුළුවන්. Exception එකක් ආවොත්, ඒක handle කරලා වෙනත් result එකක් return කරන්නත් පුළුවන්.
CompletableFuture<String> failedFuture = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Oops, something went wrong!");
});
failedFuture.exceptionally(ex -> {
System.err.println("Caught exception: " + ex.getMessage());
return "Recovered Value"; // Fallback value
}).thenAccept(result -> System.out.println("Final result: " + result));
CompletableFuture<String> handledFuture = CompletableFuture.supplyAsync(() -> {
if (new Random().nextBoolean()) {
throw new RuntimeException("Random failure!");
}
return "Success!";
}).handle((res, ex) -> {
if (ex != null) {
System.err.println("Handled exception: " + ex.getMessage());
return "Handled Failure";
} else {
return "Handled Success: " + res;
}
});
handledFuture.join(); // Wait for completion
2. Custom Executor Service භාවිතය (Using a Custom Executor Service)
CompletableFuture.supplyAsync()
වගේ methods වලට අපි ExecutorService
එකක් supply නොකරොත්, ඒක default Thread pool එකක් (ForkJoinPool.commonPool()
) භාවිත කරනවා. ඒත් මේ pool එකේ threads ගාන limited වෙන්න පුළුවන් (සාමාන්යයෙන් CPU cores ගානට සමානයි). ඒ නිසා I/O-bound operations (database calls, network calls) වලදී custom ExecutorService
එකක් භාවිත කරන එක හොඳ පුරුද්දක්. Custom pool එකක් භාවිත කිරීමෙන් default pool එක block වීම වළක්වා ගන්න පුළුවන්.
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CustomExecutorExample {
public static void main(String[] args) {
// Custom thread pool එකක් හදමු
ExecutorService customThreadPool = Executors.newFixedThreadPool(10); // Threads 10ක pool එකක්
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
System.out.println("Task 1 running in " + Thread.currentThread().getName());
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
return "Result from Task 1";
}, customThreadPool); // Custom pool එක භාවිත කරනවා
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
System.out.println("Task 2 running in " + Thread.currentThread().getName());
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
return "Result from Task 2";
}, customThreadPool); // Custom pool එක භාවිත කරනවා
CompletableFuture.allOf(task1, task2)
.thenAccept(v -> {
try {
System.out.println(task1.get());
System.out.println(task2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}).join();
customThreadPool.shutdown(); // භාවිතයෙන් පස්සේ pool එක shutdown කරන්න අමතක කරන්න එපා
}
}
3. Timeouts සලකා බැලීම (Considering Timeouts)
Asynchronous operations වලදී service එකක් respond නොකර ඉන්න පුළුවන්. ඒ වගේ වෙලාවට අනවශ්ය ලෙස බලාගෙන ඉන්නේ නැතුව operation එක timeout කරන්න පුළුවන්. Java 9 වලින් පස්සේ orTimeout()
සහ completeOnTimeout()
methods add වෙලා තියෙනවා.
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class TimeoutExample {
public static void main(String[] args) {
CompletableFuture<String> longRunningTask = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5); // Simulate a long running task
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "Task Completed";
});
// 2 seconds වලින් timeout කරන්න
longRunningTask.orTimeout(2, TimeUnit.SECONDS)
.exceptionally(ex -> {
if (ex instanceof TimeoutException) {
return "Timeout occurred! Falling back to default.";
} else {
return "An error occurred: " + ex.getMessage();
}
})
.thenAccept(System.out::println)
.join();
// Timeout වුනොත් default value එකක් දෙන්න
CompletableFuture<String> anotherTask = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5); // Simulate a long running task
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "Another Task Completed";
});
anotherTask.completeOnTimeout("Timeout Value", 2, TimeUnit.SECONDS)
.thenAccept(System.out::println)
.join();
}
}
නිගමනය (Conclusion)
ඉතින් යාලුවනේ, මේ tutorial එකෙන් Java CompletableFuture
භාවිතයෙන් asynchronous tasks කිහිපයක් එකට handle කරන්නේ කොහොමද කියන එක ගැන, විශේෂයෙන්ම allOf()
සහ anyOf()
methods ගැන ඔයාලට පැහැදිලි අවබෝධයක් ලැබෙන්න ඇති කියලා හිතනවා. මේ concepts නූතන application development වලදී performance සහ responsiveness වැඩි කරගන්න අතිශයින්ම වැදගත්.
allOf()
එකෙන් tasks ගොඩක් එකට run කරලා, හැම එකකම result එක ගන්න පුළුවන්. anyOf()
එකෙන් tasks ගොඩක් අතරින් මුලින්ම ඉවර වෙන task එකේ result එක අරගෙන වේගවත් response එකක් දෙන්න පුළුවන්. ඒ වගේම, error handling, custom thread pools, සහ timeouts වගේ දේවල් ගැනත් අපි කතා කළා.
මේවා theory විතරක් ඉගෙනගෙන වැඩක් නැහැ. ඔයාලත් මේ concepts ඔයාලගේ project වලට apply කරලා බලන්න. Code එකට අතේ ගෑවුනොත් තමයි හරියටම තේරෙන්නේ! ඔයාලගේ අත්දැකීම්, ප්රශ්න, නැත්නම් මේ ගැන අලුත් අදහස් තියෙනවා නම්, පහළින් comment එකක් දාගෙන යන්න. Programming journey එකට සුබ පැතුම්!