From 8ed3cc99f771ea63b06ea86507a3c618cf70b3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 24 May 2024 13:27:57 +0300 Subject: [PATCH] docs: update async method invocation --- async-method-invocation/README.md | 78 ++++++++++++++++--------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/async-method-invocation/README.md b/async-method-invocation/README.md index 54dfc7c64..6e6bb45e6 100644 --- a/async-method-invocation/README.md +++ b/async-method-invocation/README.md @@ -4,8 +4,10 @@ category: Concurrency language: en tag: - Asynchronous + - Decoupling - Reactive - Scalability + - Thread management --- ## Intent @@ -18,9 +20,9 @@ Asynchronous method invocation is a pattern where the calling thread is not bloc ## Explanation -Real world example +Real-world example -> Launching space rockets is an exciting business. The mission command gives an order to launch and after some undetermined time, the rocket either launches successfully or fails miserably. +> In the context of space rockets, an analogous example of the Async Method Invocation pattern can be seen in the communication between the mission control center and the onboard systems of the rocket. When mission control sends a command to the rocket to adjust its trajectory or perform a system check, they do not wait idly for the rocket to complete the task and report back. Instead, mission control continues to monitor other aspects of the mission and manage different tasks. The rocket executes the command asynchronously and sends a status update or result back to mission control once the operation is complete. This allows mission control to efficiently manage multiple concurrent operations without being blocked by any single task, similar to how asynchronous method invocation works in software systems. In plain words @@ -104,55 +106,56 @@ public class ThreadAsyncExecutor implements AsyncExecutor { Then we are ready to launch some rockets to see how everything works together. ```java -public static void main(String[]args)throws Exception{ - // construct a new executor that will run async tasks - var executor=new ThreadAsyncExecutor(); + public static void main(String[] args) throws Exception { + // construct a new executor that will run async tasks + var executor = new ThreadAsyncExecutor(); -// start few async tasks with varying processing times, two last with callback handlers -final var asyncResult1=executor.startProcess(lazyval(10,500)); -final var asyncResult2=executor.startProcess(lazyval("test",300)); -final var asyncResult3=executor.startProcess(lazyval(50L,700)); -final var asyncResult4=executor.startProcess(lazyval(20,400),callback("Deploying lunar rover")); -final var asyncResult5= - executor.startProcess(lazyval("callback",600),callback("Deploying lunar rover")); + // start few async tasks with varying processing times, two last with callback handlers + final var asyncResult1 = executor.startProcess(lazyval(10, 500)); + final var asyncResult2 = executor.startProcess(lazyval("test", 300)); + final var asyncResult3 = executor.startProcess(lazyval(50L, 700)); + final var asyncResult4 = executor.startProcess(lazyval(20, 400), + callback("Deploying lunar rover")); + final var asyncResult5 = + executor.startProcess(lazyval("callback", 600), callback("Deploying lunar rover")); - // emulate processing in the current thread while async tasks are running in their own threads - Thread.sleep(350); // Oh boy, we are working hard here - log("Mission command is sipping coffee"); + // emulate processing in the current thread while async tasks are running in their own threads + Thread.sleep(350); // Oh boy, we are working hard here + log("Mission command is sipping coffee"); -// wait for completion of the tasks -final var result1=executor.endProcess(asyncResult1); -final var result2=executor.endProcess(asyncResult2); -final var result3=executor.endProcess(asyncResult3); - asyncResult4.await(); - asyncResult5.await(); + // wait for completion of the tasks + final var result1 = executor.endProcess(asyncResult1); + final var result2 = executor.endProcess(asyncResult2); + final var result3 = executor.endProcess(asyncResult3); + asyncResult4.await(); + asyncResult5.await(); - // log the results of the tasks, callbacks log immediately when complete - log("Space rocket <"+result1+"> launch complete"); - log("Space rocket <"+result2+"> launch complete"); - log("Space rocket <"+result3+"> launch complete"); - } + // log the results of the tasks, callbacks log immediately when complete + log(String.format(ROCKET_LAUNCH_LOG_PATTERN, result1)); + log(String.format(ROCKET_LAUNCH_LOG_PATTERN, result2)); + log(String.format(ROCKET_LAUNCH_LOG_PATTERN, result3)); +} ``` Here's the program console output. -```java +``` 21:47:08.227[executor-2]INFO com.iluwatar.async.method.invocation.App-Space rocket launched successfully - 21:47:08.269[main]INFO com.iluwatar.async.method.invocation.App-Mission command is sipping coffee - 21:47:08.318[executor-4]INFO com.iluwatar.async.method.invocation.App-Space rocket<20>launched successfully - 21:47:08.335[executor-4]INFO com.iluwatar.async.method.invocation.App-Deploying lunar rover<20> - 21:47:08.414[executor-1]INFO com.iluwatar.async.method.invocation.App-Space rocket<10>launched successfully - 21:47:08.519[executor-5]INFO com.iluwatar.async.method.invocation.App-Space rocket launched successfully - 21:47:08.519[executor-5]INFO com.iluwatar.async.method.invocation.App-Deploying lunar rover +21:47:08.269[main]INFO com.iluwatar.async.method.invocation.App-Mission command is sipping coffee +21:47:08.318[executor-4]INFO com.iluwatar.async.method.invocation.App-Space rocket<20>launched successfully +21:47:08.335[executor-4]INFO com.iluwatar.async.method.invocation.App-Deploying lunar rover<20> +21:47:08.414[executor-1]INFO com.iluwatar.async.method.invocation.App-Space rocket<10>launched successfully +21:47:08.519[executor-5]INFO com.iluwatar.async.method.invocation.App-Space rocket launched successfully +21:47:08.519[executor-5]INFO com.iluwatar.async.method.invocation.App-Deploying lunar rover 21:47:08.616[executor-3]INFO com.iluwatar.async.method.invocation.App-Space rocket<50>launched successfully - 21:47:08.617[main]INFO com.iluwatar.async.method.invocation.App-Space rocket<10>launch complete - 21:47:08.617[main]INFO com.iluwatar.async.method.invocation.App-Space rocket launch complete - 21:47:08.618[main]INFO com.iluwatar.async.method.invocation.App-Space rocket<50>launch complete +21:47:08.617[main]INFO com.iluwatar.async.method.invocation.App-Space rocket<10>launch complete +21:47:08.617[main]INFO com.iluwatar.async.method.invocation.App-Space rocket launch complete +21:47:08.618[main]INFO com.iluwatar.async.method.invocation.App-Space rocket<50>launch complete ``` # Class diagram -![alt text](./etc/async-method-invocation.urm.png "Async Method Invocation") +![Async Method Invocation](./etc/async-method-invocation.urm.png "Async Method Invocation") ## Applicability @@ -196,4 +199,5 @@ Related Patterns: ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3Ti1N4f) +* [Effective Java](https://amzn.to/4cGk2Jz) * [Java Concurrency in Practice](https://amzn.to/4ab97VU)