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

并发--Callable vs Runnable

核心对比总表(Callable vs Runnable)

维度RunnableCallable
接口定义public interface Runnablepublic interface Callable<V>
核心方法void run()V call() throws Exception
返回值❌ 无返回值✅ 可返回泛型结果
异常处理❌ 只能处理非受检异常✅ 可抛出任意受检/非受检异常
执行方式Thread/Executor.execute()ExecutorService.submit()[也可以通过Thread执行,一般不用]
适用场景简单异步任务需要结果/异常处理的复杂任务

1. 接口定义与核心方法

Runnable(Java 1.0引入)

@FunctionalInterface
public interface Runnable {// 无参数、无返回值、无异常声明void run();
}

使用示例:

Runnable printTask = () -> {System.out.println("执行Runnable任务");// 不能返回结果,不能抛出受检异常
};// 执行方式
new Thread(printTask).start();
// 或
executor.execute(printTask);

Callable(Java 5引入)

public interface Callable<V> {// 返回泛型结果,可抛出任何异常V call() throws Exception;
}

使用示例:

Callable<Integer> calcTask = () -> {System.out.println("执行Callable任务");if (Math.random() > 0.8) {throw new IOException("模拟IO异常");}return 42; // 返回计算结果
};// 执行方式
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(calcTask);//使用Thread也可以,但是Callable不推荐用
FutureTask<Integer> future = new FutureTask(calcTask);
Thread t = new Thread(future);
Integer integer = future.get(); //可以获取到calcTask 返回的结果【42】

2. 异常处理机制对比

Runnable的异常困境

Runnable fileTask = () -> {try {Files.copy(source, target); // 可能抛出IOException} catch (IOException e) {// 只能转为非受检异常throw new RuntimeException(e);}
};// 未捕获异常会导致线程终止
Thread t = new Thread(fileTask);
//使用 Thread.setUncaughtExceptionHandler为线程设置异常处理器,当线程因未捕获的异常终止时会触发该处理器。
//不用Thread.setUncaughtExceptionHandler 线程x就会报错
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.println("捕获到异常: " + e.getMessage());// 可以在这里记录日志、通知其他组件等}
});
t.start();

Callable的完整异常链

Callable<String> dbTask = () -> {if (dbConnection.isClosed()) {throw new SQLException("数据库未连接");}return fetchData();
};Future<String> future = executor.submit(dbTask);try {String data = future.get();process(data);
} catch (ExecutionException e) {Throwable cause = e.getCause(); // 获取原始异常if (cause instanceof SQLException) {reconnectDatabase();}
}
http://www.xdnf.cn/news/15234.html

相关文章:

  • 代码随想录算法训练营第三十二天|LeetCode 509 斐波那契数,LeetCode 70 爬楼梯,LeetCode 746 使用最小花费爬楼梯
  • 笔记-分布式计算基础
  • 云计算三大服务模式深度解析:IaaS、PaaS、SaaS
  • zynq-PS篇——bperez77中DMA驱动注意事项
  • 飞算 JavaAI 智能编程助手:颠覆编程旧模式,重构新生态
  • 深入解析Java的G1收集器:原理、实战与优缺点
  • Umi-OCR 的 Docker安装(win制作镜像,Linux(Ubuntu Server 22.04)离线部署)
  • 企业采购成本越来越贵?根源在哪,数据怎么分析?
  • 奇哥面试记:SpringBoot整合RabbitMQ与高级特性,一不小心吊打面试官
  • 供应链管理-计划:产能策略
  • Java 并发AQS为什么是双向链表
  • [面试] 手写题-选择排序
  • 学习C++、QT---20(C++的常用的4种信号与槽、自定义信号与槽的讲解)
  • JavaAI时代:重塑企业级智能开发新范式
  • 秋招小白学数据结构-1-数据结构前置知识
  • 面向构件的编程(COP)深度解析:构建模块化系统的工程范式
  • Linux_3:进程间通信
  • (六)复习(OutBox Message)
  • 游戏的程序员会不会偷偷改自己账号的数据?
  • C++迭代器失效
  • 数据结构 顺序表(3)---顺序表的应用
  • 计算机基础:内存模型
  • 深入理解JVM的垃圾收集(GC)机制
  • 【U-Boot】Shell指令
  • 今日行情明日机会——20250711
  • 运行ssh -T git@github.com报错
  • 【工具变量】全国省市区县土地出让结果公告数据(2000-2024年)
  • 限流算法
  • time_wait状态分析
  • 数据库大文件损坏后,数据恢复操作(记录)