区别
- 两个都是接口,但是
Runnable
方法中run()
没有声明异常且没有返回值,而Callable
中call()
声明了异常且有返回值;(意味着使用Runnable
需要自己处理异常) - 通过
Callable
创建线程需要一个辅助类FutureTask
实例化对象来接收线程执行完毕后得到的结果,通过FutureTask
中的get()
获取结果,如果线程阻塞,那么就会等待。
而Runnable
中如果想要得到结果,那么就需要定义一个属性来被修改与接收,如果线程阻塞或者只有主线程和该线程,那么需要手动等待,即thread.jion();
源码
- Callable
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
- Runnable
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
观察源码看到
Runnable
中 run()
没有声明异常,且没有返回值;
Callable
中 call()
声明了异常,且有返回值。
因此使用
Runnable
创建线程的时候,需要在run()
中手动处理异常;
而Callable
方法中使用call()
则不需要
创建线程
以计算 1 到 100 的和为例
- Runnable
class MyRunnable {
static int sum = 0;
public static void main(String[] args) throws InterruptedException {
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
sum += i;
}
}
};
Thread thread = new Thread(runnable);
thread.start();
thread.join();
System.out.println(sum);
}
}
- Callable
class MyCallable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
};
FutureTask<Integer> task = new FutureTask<>(callable);
Thread thread = new Thread(task);
thread.start();
Integer res = task.get();
System.out.println(res);
}
}
可见,创建线程的方式不一样,
Runnable 比较简单
- 定义静态变量 sum;
- 重写 run();
- 将匿名 runnable 对象传入 Thread 即可;
- 然后启用 start 方法
- 最后还需要等待线程执行完毕,即调用 jion() 最后再输出结果;
Callable
- 重写 call();
- 定义局部变量 sum;
- 定义 FutureTask 类来接收结果;
- 启动线程;
- 输出结果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix