runnable 和 callable 有什么区别

简介: Runnable和Callable都是用于实现多线程的接口,区别在于返回结果、异常处理、阻塞和结果处理等方面。选择使用Runnable还是Callable取决于任务的需求和场景。

Runnable和Callable都是在Java中用于实现多线程的接口,它们的目的都是为了执行一段任务并返回结果。它们之间有以下几个主要区别:

返回结果:Runnable接口的run()方法没有返回值,它只是执行一段任务,而Callable接口的call()方法可以返回一个结果,这个结果可以是任意类型。

异常处理:Runnable接口的run()方法不能抛出异常,而Callable接口的call()方法可以抛出异常。当使用Callable时,如果任务抛出了异常,可以通过捕获Callable中的异常来处理。

是否进行阻塞:在使用Runnable时,我们通常使用Thread类来启动一个线程,并通过调用Thread的start()方法来执行Runnable的run()方法。而在使用Callable时,我们必须使用ExecutorService的submit()方法来提交Callable任务,并且它会返回一个Future对象,我们可以通过Future对象来获取执行结果。在获取Callable执行结果时,如果任务还未完成,一般会阻塞等待任务完成并获取结果。

执行结果的处理:Callable的call()方法可以返回一个Future对象,通过这个Future对象可以判断任务是否完成、取消任务执行以及获取任务执行结果。而Runnable没有这样的机制,无法直接获取任务的执行结果。

综上所述,Runnable适合那些不需要返回结果的任务,而Callable适合那些需要返回结果并可能抛出异常的任务。通常情况下,如果不需要获取任务的执行结果,可以使用Runnable接口;如果需要获取任务的执行结果,可以使用Callable接口,并结合ExecutorService的submit()方法来提交任务并获取执行结果。

下面是一个简单的示例代码,展示了如何使用Runnable和Callable:

java

import java.util.concurrent.*;

public class ThreadExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);

    // 使用Runnable
    Runnable runnableTask = () -> {
        System.out.println("Runnable task is executing.");
    };
    executor.execute(runnableTask);

    // 使用Callable
    Callable<String> callableTask = () -> {
        System.out.println("Callable task is executing.");
        return "Callable Result";
    };
    Future<String> future = executor.submit(callableTask);

    try {
        String result = future.get();
        System.out.println("Callable task result: " + result);
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

    executor.shutdown();
}

}

在这个示例中,我们创建了一个线程池,并通过ExecutorService的execute()方法执行了一个Runnable任务,以及通过submit()方法执行了一个Callable任务。在获取Callable任务的执行结果时,我们使用Future对象进行等待和获取。

总之,Runnable和Callable都是用于实现多线程的接口,区别在于返回结果、异常处理、阻塞和结果处理等方面。选择使用Runnable还是Callable取决于任务的需求和场景。

相关文章
|
5月前
面试官:除了继承Thread类和实现Runnable接口,你知道使用Callable接口的方式来创建线程吗?
面试官:除了继承Thread类和实现Runnable接口,你知道使用Callable接口的方式来创建线程吗?
19 0
面试官:除了继承Thread类和实现Runnable接口,你知道使用Callable接口的方式来创建线程吗?
|
2月前
|
Java
创建线程的三种方式:继承Thread、Runnable 接口、Callable 接口
创建线程的三种方式:继承Thread、Runnable 接口、Callable 接口
runnable 和 callable 有什么区别
runnable 和 callable 有什么区别
|
9月前
|
缓存 Java 数据库连接
线程的创建、Lambda函数式接口?Runnable和Callable之间的适配?动态修改线程任务?这里带你图解Java线程池
上面只是提到了对于Thread执行任务的一种动态实现方法,肯定还有其他的。 那么动态实现有什么好处呢? 当我们有很多个任务的时候,我们如果一直使用new,再让gc的话,那么对于系统资源的消耗无疑是巨大的。 那么这个时候,如果我们固定一下,专门拿几个线程来处理并发任务呢?但是当并发任务很多又该怎么办? 这个时候就引入了池化思想 —— Pool 什么是池? 在学JDBC的时候我们知道了连接池,在学Spring的时候,我们又接触到了对象池。 其实按理来说线程池应该是大家在初学JavaSE的时候应该就遇到的,这里我们再来讲一下。 线程池,就是用一个容器来管理线程,这个容器叫做池(Poo
89 0
线程的创建、Lambda函数式接口?Runnable和Callable之间的适配?动态修改线程任务?这里带你图解Java线程池
|
9月前
|
Java 调度
Java多线程(Thread,Runnable,Callable)附带相关面试题
1.通过继承Thread类实现多线程,2.多线程常用操作方法,3.通过Runnable接口实现多线程,4.通过Lambda与Thread结合实现快速创建多线程,5.通过实现Callable接口得到线程返回值
107 0
|
2月前
|
存储 Java
高并发编程之多线程锁和Callable&Future 接口
高并发编程之多线程锁和Callable&Future 接口
28 1
|
2月前
|
Java
Java并发编程:理解并使用Future和Callable接口
【2月更文挑战第25天】 在Java中,多线程编程是一个重要的概念,它允许我们同时执行多个任务。然而,有时候我们需要等待一个或多个线程完成,然后才能继续执行其他任务。这就需要使用到Future和Callable接口。本文将深入探讨这两个接口的用法,以及它们如何帮助我们更好地管理多线程。
|
6月前
|
Java
ExecutorService、Callable、Future实现有返回结果的多线程原理解析
ExecutorService、Callable、Future实现有返回结果的多线程原理解析
34 0
|
6月前
|
存储 Java
并发编程系列教程(09) - Callable与Future模式
并发编程系列教程(09) - Callable与Future模式
25 0
|
9月前
|
Java
【并发技术11】Callable与Future的应用
【并发技术11】Callable与Future的应用