# Automatic Refactoring Approach for Asynchronous Mechanisms with CompletableFuture
## 3 Motivation  
To visually demonstrate the advantages of CompletableFuture over traditional asynchronous constructs in asynchronous code, we illustrate this through a code example adapted from a classic concurrent programming case provided in Section 6.3 of \"Java Concurrency in Practice\" [22]. Our example code primarily involves two tasks: first, fetching images from a remote server based on a provided list of image information, and second, decrypting the fetched images, both performed asynchronously. In this section, we first show the shortcomings of traditional asynchronous constructs when handling multiple dependent asynchronous tasks, followed by a demonstration of how transitioning to CompletableFuture constructs allows developers to use its rich API to make asynchronous code concise and clear while also enhancing program performance. In traditional asynchronous constructs, as shown in Figure 1, line 3 uses the submit method to submit getImageFile() to a download thread pool suitable for IO-intensive operations and returns a Future object, thus obtaining a List<Future<ImageFile> type list called imageFileFutures. Subsequently, the fetched images are decrypted; line 7 uses the get method of the Future interface to synchronously block and obtain the results of the IO tasks, which are then submitted for decryption in the decryption thread pool at line 9. This asynchronous approach has two drawbacks. In terms of code readability, the asynchronous logic (decrypting images depends on the completion of the image fetching task) is not evident in the code of Figure 1. Consider if there were more than these two asynchronous tasks; the complexity of dependencies between these tasks would significantly increase, further reducing the readability of asynchronous code and complicating future maintenance. Performance-wise, interaction between two or more asynchronous tasks requires the main thread to block and wait, as shown in Figure 1, line 7. During the waiting period for one asynchronous task in imageFileFutures, even if other IO asynchronous tasks are completed, they cannot be promptly submitted to the decryption tasks, failing to fully leverage the advantages of asynchronous programming. In other words, blocking waiting is a synchronous operation that affects asynchronous efficiency. After transitioning from traditional asynchronous constructs to CompletableFuture, the changes to the code are minimal. As shown in Figure 2, unlike Figure 1, the modifications occur in lines 3 and 9, where developers can easily understand these changes. Figure 1: Remote Acquisition and Decryption of Images. The ordinary Future initially returned by traditional asynchronous constructs has been converted to CompletableFuture, allowing developers to utilize its extensive API. After a comprehensive assessment of the software project, if developers determine that removing the synchronous blocking get() method invocations will not affect the program's normal operation, they can switch to completely asynchronous, streamlined code. As shown in Figure 3, developers use the CompletableFuture API to orchestrate these two interdependent asynchronous tasks. At line 4, they first use the static method supplyAsync() to submit the task of fetching images to the corresponding thread pool executor. Then, at line 5, the member method thenApplyAsync() is used to submit the decryption task to the corresponding thread pool executor. This demonstrates that CompletableFuture not only makes the dependencies between asynchronous tasks very clear but also allows interdependent asynchronous tasks to be executed completely asynchronously, overcoming the drawbacks of traditional asynchronous constructs. To assess the impact of fully asynchronous execution of multiple asynchronous tasks with dependencies on program performance, we manually refactored the test case RunTest.timezoneOfID from the open-source project Jenkins and conducted measurements using the JMH benchmarking tool with 10 warm-ups followed by 10 measurements.