实现异步回调

本文详细介绍了Java中的异步回调机制,包括基本的异步任务接口、回调接口的实现,以及如何使用线程池管理和异步任务的取消。此外,还探讨了CompletableFuture在简化异步编程中的应用。
摘要由CSDN通过智能技术生成

一、什么是异步回调

当一个异步操作被触发时,程序可以继续执行后续代码而不必等待该操作完成。一旦异步操作完成(无论是成功还是失败),会调用一个事先定义好的函数,这个函数就是“回调函数”。回调函数会处理异步操作的结果(比如处理数据或者处理错误)。

二、自己一步步实现一个异步回调架子

2.1 最基础版本

首先,定义一个异步任务接口,该接口代表了将要异步执行的任务。

@FunctionalInterface
public interface AsyncTask<T> {
    T execute() throws Exception;
}

定义回调接口

public interface Callback<T> {
    void onSuccess(T result);
    void onFailure(Exception e);
}

实现异步任务执行器

public class AsyncTaskExecutor {

    public <T> void executeAsync(AsyncTask<T> task, Callback<T> callback) {
        new Thread(() -> {
            try {
                T result = task.execute(); // 执行异步任务
                callback.onSuccess(result); // 调用成功回调
            } catch (Exception e) {
                callback.onFailure(e); // 调用失败回调
            }
        }).start();
    }
}
2.2 使用线程池处理提交的任务

改进AsyncTaskExecutor

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AsyncTaskExecutor {
    private final ExecutorService executor;

    public AsyncTaskExecutor(int numberOfThreads) {
        this.executor = Executors.newFixedThreadPool(numberOfThreads);
    }

    public <T> void executeAsync(AsyncTask<T> task, Callback<T> callback) {
        executor.submit(() -> {
            try {
                T result = task.execute(); // 执行异步任务
                callback.onSuccess(result); // 调用成功回调
            } catch (Exception e) {
                callback.onFailure(e); // 调用失败回调
            }
        });
    }

    public void shutdown() {
        executor.shutdown();
    }
}

2.3 使用单独的线程池执行回调

改进AsyncTaskExecutor

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AsyncTaskExecutor {
    private final ExecutorService taskExecutor;
    private final ExecutorService callbackExecutor;

    public AsyncTaskExecutor(int taskThreads, int callbackThreads) {
        this.taskExecutor = Executors.newFixedThreadPool(taskThreads);
        this.callbackExecutor = Executors.newFixedThreadPool(callbackThreads);
    }

    public <T> void executeAsync(AsyncTask<T> task, Callback<T> callback) {
        taskExecutor.submit(() -> {
            try {
                T result = task.execute(); // 在任务线程池中执行异步任务
                callbackExecutor.submit(() -> callback.onSuccess(result)); // 在回调线程池中执行成功回调
            } catch (Exception e) {
                callbackExecutor.submit(() -> callback.onFailure(e)); // 在回调线程池中执行失败回调
            }
        });
    }

    public void shutdown() {
        // 关闭两个线程池
        try {
            taskExecutor.shutdown();
            callbackExecutor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.4 支持取消异步任务

利用Future接口提供的取消机制。当通过线程池提交一个任务时,它会返回一个Future对象,可以使用这个对象来取消任务或检查任务是否已经完成或被取消。

改进AsyncTaskExecutor

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class AsyncTaskExecutor {
    private final ExecutorService taskExecutor;
    private final ExecutorService callbackExecutor;

    public AsyncTaskExecutor(int taskThreads, int callbackThreads) {
        this.taskExecutor = Executors.newFixedThreadPool(taskThreads);
        this.callbackExecutor = Executors.newFixedThreadPool(callbackThreads);
    }

    public <T> Future<?> executeAsync(AsyncTask<T> task, Callback<T> callback) {
        return taskExecutor.submit(() -> {
            try {
                T result = task.execute(); // 在任务线程池中执行异步任务
                callbackExecutor.submit(() -> callback.onSuccess(result)); // 在回调线程池中执行成功回调
            } catch (Exception e) {
                callbackExecutor.submit(() -> callback.onFailure(e)); // 在回调线程池中执行失败回调
            }
        });
    }

    public void shutdown() {
        try {
            taskExecutor.shutdown();
            callbackExecutor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用示例:

public class AsyncDemo {
    public static void main(String[] args) {
        AsyncTaskExecutor executor = new AsyncTaskExecutor(10, 5);

        Future<?> future = executor.executeAsync(() -> {
            // 这是一个异步任务示例
            Thread.sleep(1000); // 模拟耗时操作
            return "任务结果";
        }, new Callback<String>() {
            @Override
            public void onSuccess(String result) {
                // 成功回调
                System.out.println("异步任务成功完成,结果:" + result);
            }

            @Override
            public void onFailure(Exception e) {
                // 失败回调
                System.out.println("异步任务执行失败");
                e.printStackTrace();
            }
        });

        // 根据需要取消任务
        // 注意:取消正在执行的任务可能不会立即停止任务,且不是所有任务都可以取消
        boolean cancelResult = future.cancel(true); // 参数true表示如果任务正在运行,应该被中断

        if (cancelResult) {
            System.out.println("任务已取消");
        } else {
            System.out.println("任务取消失败,可能已经完成或无法取消");
        }

        // 注意:在实际应用中,关闭线程池的操作应当放在应用关闭或者确定不再提交任何任务时进行
        // executor.shutdown();
    }
}

三、使用CompletableFuture

CompletableFuture是Java提供的异步回调工具,内部默认使用ForkJoinPool线程池。
使用示例:

CompletableFuture.supplyAsync(() -> {
    // 异步执行的任务
    return "异步结果";
}).thenAccept(result -> {
    // 处理结果
    System.out.println("异步任务的结果是: " + result);
}).exceptionally(e -> {
    // 异常处理
    e.printStackTrace();
    return null;
});

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值