当前位置: 首页>数据库>正文

教你如何判断Java代码中异步操作是否完成

1. 使用Future和Callable

Java中的Future接口定义了一种方式来表示异步操作的未来结果。我们可以使用Callable接口来定义异步任务,它返回一个Future对象,我们可以利用Future对象的方法来检查任务是否完成。 下面是一个例子:

javaCopy code

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;publicclass AsyncDemo {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? ExecutorService executorService = Executors.newSingleThreadExecutor();

? ? ? ? // 定义异步任务Callable asyncTask = () -> {

? ? ? ? ? ? Thread.sleep(2000);// 模拟耗时操作return"Async task completed";

? ? ? ? };

? ? ? ? // 提交异步任务Future future = executorService.submit(asyncTask);

? ? ? ? // 判断任务是否完成while(!future.isDone()) {

? ? ? ? ? ? System.out.println("Task not done yet...");

? ? ? ? ? ? Thread.sleep(500);

? ? ? ? }

? ? ? ? // 获取结果String result = future.get();

? ? ? ? System.out.println(result);

? ? ? ? // 关闭线程池? ? ? ? executorService.shutdown();

? ? }

}

在上面的代码中,我们创建了一个单线程的ExecutorService来执行异步任务。我们使用submit方法提交异步任务,并得到一个Future对象。然后,我们可以使用isDone()方法来判断任务是否完成,如果任务没有完成,则等待片刻后再次检查。一旦任务完成,我们可以使用get()方法获取任务的结果。

2. 使用CompletableFuture

自Java 8起,Java提供了CompletableFuture类来更加方便地处理异步操作。CompletableFuture是Future的一个实现,同时也支持对未来结果的处理和组合。 下面是一个例子:

javaCopy code

import java.util.concurrent.CompletableFuture;

import java.util.concurrent.TimeUnit;publicclass AsyncDemo {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? // 定义异步任务CompletableFuture future = CompletableFuture.supplyAsync(() -> {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? TimeUnit.SECONDS.sleep(2);// 模拟耗时操作}catch (InterruptedException e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? ? ? return"Async task completed";

? ? ? ? });

? ? ? ? // 判断任务是否完成while(!future.isDone()) {

? ? ? ? ? ? System.out.println("Task not done yet...");

? ? ? ? ? ? TimeUnit.MILLISECONDS.sleep(500);

? ? ? ? }

? ? ? ? // 获取结果String result = future.get();

? ? ? ? System.out.println(result);

? ? }

}

在上述代码中,我们使用supplyAsync方法创建了一个CompletableFuture对象,并定义了异步任务。然后,我们可以使用isDone()方法来判断任务是否完成。通过调用get()方法可以获取最终的结果。

当涉及到实际应用场景时,异步操作的一个常见用例是在Web应用中执行并行的HTTP请求以提高性能。以下是一个示例代码,展示了如何使用异步操作来执行多个HTTP请求,并在所有请求完成后进行处理。

javaCopy code

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.*;publicclass AsyncHttpExample {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? List> futures =newArrayList<>();

? ? ? ? ExecutorService executor = Executors.newFixedThreadPool(5);

? ? ? ? List urls = List.of(

? ? ? ? ? ? ? ? "https://www.example.com/api1",

? ? ? ? ? ? ? ? "https://www.example.com/api2",

? ? ? ? ? ? ? ? "https://www.example.com/api3"? ? ? ? );

? ? ? ? for (String url : urls) {

? ? ? ? ? ? Callable task = () -> {

? ? ? ? ? ? ? ? return performRequest(url);

? ? ? ? ? ? };

? ? ? ? ? ? Future future = executor.submit(task);

? ? ? ? ? ? futures.add(future);

? ? ? ? }

? ? ? ? executor.shutdown();

? ? ? ? for(Future future : futures) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? String result = future.get();

? ? ? ? ? ? ? ? System.out.println("Received response: "+ result);

? ? ? ? ? ? } catch(InterruptedException | ExecutionException e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? privatestatic String performRequest(String url) throws IOException {

? ? ? ? HttpURLConnection connection =null;

? ? ? ? BufferedReader reader =null;

? ? ? ? StringBuilder response =new StringBuilder();

? ? ? ? try {

? ? ? ? ? ? URL requestUrl =new URL(url);

? ? ? ? ? ? connection = (HttpURLConnection) requestUrl.openConnection();

? ? ? ? ? ? connection.setRequestMethod("GET");

? ? ? ? ? ? reader =newBufferedReader(new InputStreamReader(connection.getInputStream()));

? ? ? ? ? ? String line;

? ? ? ? ? ? while((line = reader.readLine()) !=null) {

? ? ? ? ? ? ? ? response.append(line);

? ? ? ? ? ? }

? ? ? ? } finally {

? ? ? ? ? ? if(connection !=null) {

? ? ? ? ? ? ? ? connection.disconnect();

? ? ? ? ? ? }

? ? ? ? ? ? if(reader !=null) {

? ? ? ? ? ? ? ? reader.close();

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return response.toString();

? ? }

}

在这个示例中,我们创建了一个固定大小的线程池,并为每个URL创建了一个异步任务。每个任务在自己的线程中执行HTTP请求,并返回响应结果。我们使用Future来跟踪每个任务的执行状态和结果。一旦所有任务都被提交,我们调用shutdown()方法关闭线程池,然后通过迭代每个Future对象,使用get()方法获取任务的结果。最后,我们可以根据需要对结果进行进一步处理,这里只是简单地打印出每个请求的响应。

java.util.concurrent.Callable?是 Java 并发编程中的一个接口,它表示一个可调用的任务,可以在计算中返回一个值。与?Runnable?接口不同,Callable?接口的?call()?方法可以返回一个结果,并且可以在执行过程中抛出受检异常。?Callable?接口定义了以下方法:

V call() throws Exception:执行任务并返回结果。可以抛出受检异常。

boolean equals(Object obj):比较该?Callable?与指定对象是否相等。

default <U> Callable<U> compose(Function<super V, extends U> var1):将该?Callable?的结果应用于给定函数,并返回?Callable。

default <V2> Callable<V2> andThen(Function<super V, extends V2> var1):将给定函数应用于该?Callable?的结果,并返回新的?Callable。

default Predicate<V> isEqual(Object var1):返回谓词,用于判断对象是否与这个?Callable?的结果相等。

default Supplier<V> toSupplier():返回将该?Callable?的结果作为值的供应商。 在实际应用中,Callable?接口常常与?ExecutorService?结合使用,通过将?Callable?对象提交给线程池来执行。线程池会返回一个?Future?对象,用于跟踪任务的执行状态和获取结果。 以下是一个示例代码,展示了如何使用?Callable?接口:

javaCopy code

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;publicclass CallableExample {

? ? publicstaticvoid main(String[] args) throws Exception {

? ? ? ? Callable task = () -> {

? ? ? ? ? ? intsum =0;

? ? ? ? ? ? for(inti =1; i <=100; i++) {

? ? ? ? ? ? ? ? sum += i;

? ? ? ? ? ? }

? ? ? ? ? ? return sum;

? ? ? ? };

? ? ? ? ExecutorService executor = Executors.newSingleThreadExecutor();

? ? ? ? Future future = executor.submit(task);

? ? ? ? // 可以在此处执行其他任务? ? ? ?

? ? ? ? Integer result = future.get();// 获取任务的结果,会阻塞直到任务完成System.out.println("Sum: "+ result);

? ? ? ? executor.shutdown();

? ? }

}

散热风扇https://www.uv-semi.com/

深圳网站建设www.sz886.com


https://www.xamrdz.com/database/6ys1995281.html

相关文章: