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

412 阅读3分钟

在Java中,异步操作的实现方式有很多,最常见的是通过多线程并发工具类来实现。

在这个示例中,我们定义了一个Callable任务,使用ExecutorService提交该任务,并通过Future对象检查任务是否完成以及获取任务结果。

java

import java.util.concurrent.*;

public class FutureExample {
    public static void main(String[] args) {
        // 创建一个固定线程池
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // 定义一个Callable任务,任务会返回一个字符串结果
        Callable<String> callableTask = () -> {
            // 模拟任务执行耗时
            Thread.sleep(2000);
            return "Task completed!";
        };

        // 提交任务并获取Future对象
        Future<String> future = executor.submit(callableTask);

        try {
            // 判断任务是否完成
            while (!future.isDone()) {
                System.out.println("Task is still not done...");
                Thread.sleep(500); // 每隔500毫秒检查一次任务是否完成
            }

            // 获取任务结果
            String result = future.get();
            System.out.println("Task result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        } finally {
            // 关闭线程池
            executor.shutdown();
        }
    }
}

异步操作在Web应用中的实践

通过异步任务并行执行多个HTTP请求,从而减少响应时间。

这个示例展示了如何使用ExecutorService并行执行两个HTTP请求,并获取结果.

java

import java.util.concurrent.*;
import java.net.*;
import java.io.*;

public class AsyncHttpExample {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 创建一个固定线程池
        ExecutorService executor = Executors.newFixedThreadPool(4);

        // 定义第一个HTTP请求任务
        Callable<String> task1 = () -> fetch("http://example.com/api/endpoint1");
        // 定义第二个HTTP请求任务
        Callable<String> task2 = () -> fetch("http://example.com/api/endpoint2");

        // 提交任务并获取Future对象
        Future<String> future1 = executor.submit(task1);
        Future<String> future2 = executor.submit(task2);

        // 获取任务结果
        String result1 = future1.get();
        String result2 = future2.get();

        System.out.println("Result 1: " + result1);
        System.out.println("Result 2: " + result2);

        // 关闭线程池
        executor.shutdown();
    }

    // 执行HTTP请求的方法
    private static String fetch(String urlString) throws IOException {
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");

        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String inputLine;
        StringBuilder content = new StringBuilder();
        while ((inputLine = in.readLine()) != null) {
            content.append(inputLine);
        }

        in.close();
        return content.toString();
    }
}

在实际开发中,异步操作不仅仅是提交和获取任务结果,还需要考虑错误处理结果组合异步流等高级技巧。

错误处理和异常传播

异步操作中发生的异常需要适当地处理和传播,确保程序的健壮性。

在这个示例中,我们模拟了一个任务抛出异常,并使用exceptionally方法处理异常。

java

import java.util.concurrent.*;

public class CompletableFutureErrorHandling {
    public static void main(String[] args) {
        // 创建一个CompletableFuture任务
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            if (true) {
                throw new RuntimeException("Something went wrong!");
            }
            return "Hello, CompletableFuture!";
        });

        // 处理结果或异常
        future.thenAccept(result -> System.out.println("Result: " + result))
              .exceptionally(ex -> {
                  // 异常处理
                  System.out.println("Exception: " + ex);
                  return null;
              });

        try {
            // 主线程等待异步任务完成
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果组合和异步流

使用CompletableFuture的thenCombine方法来组合两个异步任务的结果。

以下是一个使用thenCombine方法组合两个异步任务结果的示例:

java

import java.util.concurrent.*;

public class CompletableFutureCombine {
    public static void main(String[] args) {
        // 创建两个异步任务
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);


            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Task 1 completed!";
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Task 2 completed!";
        });

        // 组合两个任务的结果
        CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {
            return result1 + " and " + result2;
        });

        // 处理组合结果
        combinedFuture.thenAccept(result -> System.out.println("Combined Result: " + result));

        try {
            // 主线程等待异步任务完成
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!