当前位置: 首页 > news >正文

Java Callback 实现线程切换以及与Kotlin原理关系

案例

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;// 1. 定义回调接口
public interface ThreadSwitchCallback {void onSuccess(String result);    // 成功回调void onFailure(Exception error); // 失败回调void onProgress(int progress);   // 进度更新回调
}// 2. 模拟耗时任务执行器
public class AsyncTaskExecutor {private final ExecutorService threadPool = Executors.newFixedThreadPool(2);// 3. 执行异步任务(接受回调参数)public void executeTask(final String input, final ThreadSwitchCallback callback) {threadPool.execute(() -> {try {// 在工作线程执行耗时操作for (int i = 0; i <= 100; i += 10) {Thread.sleep(200); // 模拟工作callback.onProgress(i); // 进度更新回调}// 模拟处理结果String result = "Processed: " + input.toUpperCase();// 4. 切换到主线程(UI线程)回调结果switchToMainThread(() -> callback.onSuccess(result));} catch (Exception e) {// 5. 错误处理(切换到主线程)switchToMainThread(() -> callback.onFailure(e));}});}// 6. 模拟切换到主线程的方法private void switchToMainThread(Runnable action) {// 在实际Android中应使用 new Handler(Looper.getMainLooper()).post(action)// 这里使用简单模拟new Thread(() -> {try {Thread.sleep(50); // 模拟线程切换延迟System.out.println("【切换到主线程】");action.run();} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}// 7. 主程序(模拟Android UI线程)
public class CallbackDemo {public static void main(String[] args) {System.out.println("【主线程】启动 - " + Thread.currentThread().getName());AsyncTaskExecutor executor = new AsyncTaskExecutor();// 8. 创建回调实现ThreadSwitchCallback callback = new ThreadSwitchCallback() {@Overridepublic void onSuccess(String result) {System.out.println("【回调结果】" + result + " - 线程: " + Thread.currentThread().getName());}@Overridepublic void onFailure(Exception error) {System.err.println("【回调错误】" + error.getMessage());}@Overridepublic void onProgress(int progress) {System.out.println("【进度更新】" + progress + "% - 线程: " + Thread.currentThread().getName());}};// 9. 执行异步任务System.out.println("【主线程】启动异步任务");executor.executeTask("Hello Callback", callback);// 10. 主线程继续执行其他任务System.out.println("【主线程】继续执行其他任务...");// 保持程序运行(模拟Android生命周期)try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}
}

运行结果示例

【主线程】启动 - main
【主线程】启动异步任务
【主线程】继续执行其他任务...
【进度更新】0% - 线程: Thread-0
【进度更新】10% - 线程: Thread-0
【进度更新】20% - 线程: Thread-0
【进度更新】30% - 线程: Thread-0
【进度更新】40% - 线程: Thread-0
【进度更新】50% - 线程: Thread-0
【进度更新】60% - 线程: Thread-0
【进度更新】70% - 线程: Thread-0
【进度更新】80% - 线程: Thread-0
【进度更新】90% - 线程: Thread-0
【进度更新】100% - 线程: Thread-0
【切换到主线程】
【回调结果】Processed: HELLO CALLBACK - 线程: Thread-1

核心机制解析

1. 回调接口定义
public interface ThreadSwitchCallback {void onSuccess(String result);void onFailure(Exception error);void onProgress(int progress);
}
  • 定义线程切换后需要执行的操作

  • 包含成功、失败、进度更新三种回调类型

2. 线程切换关键实现
private void switchToMainThread(Runnable action) {new Thread(() -> {Thread.sleep(50); // 模拟线程切换延迟System.out.println("【切换到主线程】");action.run(); // 在主线程执行回调}).start();
}

回调机制的优缺点

优点:

  1. 明确的异步操作分离

  2. 支持多状态回调(成功/失败/进度)

  3. 兼容各种 Java 版本

  4. 线程切换逻辑清晰可见

缺点:

  1. 嵌套回调导致"金字塔"代码结构

  2. 错误处理分散在不同回调中

  3. 需要手动管理线程切换

  4. 回调接口定义繁琐(需创建多个接口)

与 Kotlin 协程对比

特性Java 回调Kotlin 协程
代码结构嵌套回调线性同步风格
线程切换手动使用 Handler自动通过 Dispatchers
错误处理分散在各回调集中 try-catch
并发控制需手动同步async/await 简化
内存开销多个回调对象共享状态机
学习曲线简单直接概念较复杂

关键区别:协程本质上也是基于回调机制,但通过编译器将回调转换为状态机,使代码保持线性结构。回调是显式线程切换,协程是隐式线程切换。

http://www.lryc.cn/news/615493.html

相关文章:

  • 数码管的使用(STC8)
  • Pytest中实现自动生成测试用例脚本代码
  • Java Stream 使用 Fork/Join框架的分治任务模型
  • Windows 安装 Xinference 速记
  • CPU缓存(CPU Cache)和TLB(Translation Lookaside Buffer)缓存现代计算机体系结构中用于提高性能的关键技术
  • 【线性代数】线性方程组与矩阵——(2)矩阵与线性方程组的解
  • 计算机网络:深入了解CIDR地址块如何利用VLSM进行子网划分的过程
  • 前端视角下关于 WebSocket 的简单理解
  • 如何在 Ubuntu 24.04 LTS Linux 上安装 Azure Data Studio
  • 【排序算法】④堆排序
  • 基于STM32H5的非循环GPDMA链表使用
  • LangChain-Unstructured 基础使用:PDF 与 Markdown 处理解析
  • 基于IPD体系的研发项目范围管理
  • 【网络与爬虫 52】Scrapyd-k8s集群化爬虫部署:Kubernetes原生分布式爬虫管理平台实战指南
  • 一个app项目周期是多久?
  • Java异常:认识异常、异常的作用、自定义异常
  • 世界时(Universal Time, UT)的定义与详解
  • 小学数学训练闭环:出题、作答、批改一体化方案实践
  • [Oracle] MAX()和MIN()函数
  • 【Python 高频 API 速学 ④】
  • LintCode第547题-两数组的交集
  • 腾讯COS云存储入门
  • 浅尝AI辅助C转Verilog方法
  • 新手小白使用jQuery在实际开发中常用到的经验
  • 第二十天:余数相同问题
  • 《Resolving tissue complexity by multimodal spatial omics modeling with MISO》
  • 【面试场景题】微博热点新闻系统设计方案
  • day18 - CSS函数
  • nginx高性能web服务器
  • 基于Prometheus、Grafana、Loki与Tempo的统一监控平台故障排查与解决方案