在 Java 中,回调(Callback)和异步回调(Asynchronous Callback)都可以通过接口、匿名类或 lambda 表达式来实现。下面我将分别展示如何在 Java 中实现回调和异步回调。
同步回调示例
在同步回调中,任务完成后立即调用回调函数,整个过程是阻塞的。
代码示例:
// 定义一个回调接口
interface TaskCompleteListener {
void onTaskComplete();
}
// 一个执行任务的类,它接收回调接口
class Task {
public void execute(TaskCompleteListener listener) {
System.out.println("Executing task...");
// 模拟任务执行
try {
Thread.sleep(1000); // 模拟1秒的任务
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task completed!");
// 调用回调方法
listener.onTaskComplete();
}
}
// 主程序
public class CallbackExample {
public static void main(String[] args) {
Task task = new Task();
// 传递回调接口的实现
task.execute(new TaskCompleteListener() {
@Override
public void onTaskComplete() {
System.out.println("Callback: Task is finished!");
}
});
}
}
输出:
Executing task...
Task completed!
Callback: Task is finished!
在这个例子中,Task 类执行任务并在任务完成后调用 TaskCompleteListener 接口的 onTaskComplete 方法。主程序将回调接口的实现传递给 Task,使得任务完成时调用这个回调。
异步回调示例
在异步回调中,任务是非阻塞的,程序会在异步任务执行的同时继续执行其他代码,任务完成后会调用回调函数。
代码示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// 定义一个回调接口
interface DownloadCompleteListener {
void onDownloadComplete();
}
// 一个模拟异步下载任务的类
class FileDownloader {
public void downloadFileAsync(DownloadCompleteListener listener) {
// 使用线程池来模拟异步任务
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
System.out.println("Downloading file...");
// 模拟下载任务(比如耗时3秒)
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Download completed!");
// 下载完成后调用回调
listener.onDownloadComplete();
});
executor.shutdown(); // 关闭线程池
}
}
// 主程序
public class AsyncCallbackExample {
public static void main(String[] args) {
FileDownloader downloader = new FileDownloader();
// 传递回调接口的实现
downloader.downloadFileAsync(new DownloadCompleteListener() {
@Override
public void onDownloadComplete() {
System.out.println("Callback: File download finished!");
}
});
// 主线程继续执行其他任务
System.out.println("Main thread is free to do other tasks...");
}
}
输出:
Downloading file...
Main thread is free to do other tasks...
Download completed!
Callback: File download finished!
在这个例子中,FileDownloader 类模拟了一个异步文件下载任务,使用 ExecutorService 提供异步执行能力。当文件下载完成后,它调用 DownloadCompleteListener 的 onDownloadComplete 方法。与此同时,主线程不会等待下载任务完成,它继续执行其他任务,体现了异步回调的特性。
关键点:
同步回调:任务执行完毕后立即调用回调函数,整个过程是阻塞的。
异步回调:任务在后台异步执行,程序继续运行其他逻辑,任务完成后通过回调通知主程序。
线程池与异步操作:
在异步回调中,我们通过 ExecutorService 创建线程池,异步执行耗时操作(如文件下载、网络请求等)。在 Java 中,ExecutorService 提供了方便的线程管理工具,适合处理异步回调的场景。
这样你可以根据需求选择同步或异步回调机制,特别是当你有耗时操作时,异步回调是避免阻塞主线程的常用方案。