Yes, Java has an equivalent mechanism for asynchronous programming, similar to C#'s async/await. In Java, this is typically done using the CompletableFuture class, which was introduced in Java 8. CompletableFuture allows you to write non-blocking, asynchronous code using a more functional and fluent programming style.

Here's an example to illustrate how you might use CompletableFuture in Java:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class AsyncExample {
    public static void main(String[] args) {
        // Start an asynchronous task
        CompletableFuture<String> asyncTask = CompletableFuture.supplyAsync(() -> {
            try {
                // Simulate a long-running task
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello, World!";
        });

        // Continue with other tasks while the async task is running
        System.out.println("Doing other work...");

        // When the async task is done, use the result
        asyncTask.thenAccept(result -> {
            System.out.println("Async task completed. Result: " + result);
        });

        // Keep the main thread alive so the async task has time to complete
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

In this example, we create a CompletableFuture that simulates a long-running task. The task runs asynchronously, allowing the main thread to continue executing other tasks. When the async task is done, the thenAccept method is called, and we can use the result.

While CompletableFuture is not exactly the same as C#'s async/await, it provides a similar mechanism for writing asynchronous code in Java. It's also worth noting that Java's CompletableFuture can be more powerful and flexible, as it provides many other methods for combining, chaining, and manipulating asynchronous tasks.


Is the principle of CompletableFuture still Thread?


Yes, the principle of CompletableFuture is still based on threads. Under the hood, CompletableFuture relies on Java's built-in thread handling and the Executor framework to manage asynchronous execution.

When you create a CompletableFuture using methods like supplyAsync, runAsync, or completedFuture, you have the option to provide an Executor to determine how the asynchronous task will be executed. If you don't provide an Executor, the CompletableFuture will use the default ForkJoinPool.commonPool() as its execution environment, which is a shared thread pool available to all applications.

Here's an example of creating a CompletableFuture with a custom Executor:

import java.util.concurrent.*;

public class CustomExecutorExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(4);

        CompletableFuture<String> asyncTask = CompletableFuture.supplyAsync(() -> {
            // Your asynchronous task code here
            return "Result";
        }, executor);

        // Use the result of the async task
        asyncTask.thenAccept(System.out::println);

        // Shutdown the executor when you're done
        executor.shutdown();
    }
}

In this example, we create a custom ExecutorService with a fixed thread pool of 4 threads. When creating the CompletableFuture, we provide our custom Executor as the second parameter to supplyAsync.

While CompletableFuture is still based on threads, it abstracts away much of the complexity of working with threads directly. It provides a higher-level, functional API for managing asynchronous tasks, which can make your code more readable and easier to maintain.


Decompose the above code instead of using Lambda.


Sure! Here's the same code as in your example, but without using a lambda expression. Instead, we'll use an anonymous inner class implementing the Supplier interface:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public class AsyncExampleWithoutLambda {
    public static void main(String[] args) {
        // Start an asynchronous task
        CompletableFuture<String> asyncTask = CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                try {
                    // Simulate a long-running task
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "Hello, World!";
            }
        });

        // Continue with other tasks while the async task is running
        System.out.println("Doing other work...");

        // When the async task is done, use the result
        asyncTask.thenAccept(new Consumer<String>() {
            @Override
            public void accept(String result) {
                System.out.println("Async task completed. Result: " + result);
            }
        });

        // Keep the main thread alive so the async task has time to complete
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

下面的两处代码更改前后顺序对结果没有影响

// When the async task is done, use the result
asyncTask.thenAccept(new Consumer<String>() {
    @Override
    public void accept(String result) {
        System.out.println("Async task completed. Result: " + result);
    }
});

// Continue with other tasks while the async task is running
System.out.println("Doing other work...");

In this example, instead of using a lambda expression for the supplyAsync method, we've created an anonymous inner class implementing the Supplier<String> interface. Similarly, for the thenAccept method, we've created an anonymous inner class implementing the Consumer<String> interface.

The behavior of the code is identical to the previous example using lambda expressions; the only difference is the syntax.


Answer by ChatGPT-4

标签: none

评论已关闭