在Java中设计并发线程时,使用Runnable接口和Callable接口有什么区别,为什么你会选择其中一个而不是另一个?


当前回答

可调用的和可运行的都彼此相似,可以在实现线程中使用。在实现Runnable的情况下,你必须实现run()方法,但在可调用的情况下,你必须实现call()方法,这两种方法的工作方式相似,但可调用的call()方法有更大的灵活性。他们之间有一些不同。

Runnable和callable之间的区别如下所示

1) runnable的run()方法返回void,这意味着如果你想让你的线程返回一些你可以进一步使用的东西,那么你没有选择runnable run()方法。有一个解决方案'Callable',如果你想返回任何形式的对象,那么你应该使用Callable而不是Runnable。可调用接口有方法'call()',该方法返回Object。

方法签名- 可运行- >

public void run(){}

可调用的- - - >

public Object call(){}

2)对于Runnable run()方法,如果出现任何检查异常,那么你必须用try catch块处理,但对于Callable call()方法,你可以抛出检查异常,如下所示

 public Object call() throws Exception {}

3) Runnable来自遗留的java 1.0版本,而callable来自java 1.5版本的Executer框架。

如果你熟悉Executers,那么你应该使用Callable而不是Runnable。

希望你能理解。

其他回答

除了所有其他答案:

我们不能传递/使用Callable到单独的线程执行,即Callable只能在执行器框架中使用。 但是,Runnable可以传递给一个单独的线程执行(new thread (new CustomRunnable())),也可以在Executor Framework中使用。

Java功能接口

它是一种与函数式编程相匹配的接口命名约定

//Runnable
interface Runnable {
    void run();
}

//Action - throws exception
interface Action {
    void run() throws Exception;
}

//Consumer - consumes a value/values, throws exception
//BiConsumer, 
interface Consumer1<T> {
    void accept(T t) throws Exception;
}

//Callable - return result, throws exception
interface Callable<R> {
    R call() throws Exception;
}

//Supplier - returns result, throws exception
interface Supplier<R> {
    R get() throws Exception;
}

//Predicate - consumes a value/values, returns true or false, throws exception
interface Predicate1<T> {
    boolean test(T t) throws Exception;
}

//Function - consumes a value/values, returns result, throws exception
//BiFunction, Function3...
public interface Function1<T, R> {
    R apply(T t) throws Exception;
}

...

//Executor
public interface Executor {
    void execute(Runnable command);
}

【快速闭包命名】

Callable和Runnable之间的区别如下:

在JDK 5.0中引入了Callable,而在JDK 1.0中引入了Runnable 可调用对象有call()方法,而Runnable有run()方法。 可调用对象有返回值的call方法,而可运行对象有不返回任何值的run方法。 调用方法可以抛出检查异常,但运行方法不能抛出检查异常。 可调用的使用submit()方法放入任务队列,可运行的使用execute()方法放入任务队列。

Callable需要实现call()方法,而Runnable需要实现run()方法。 Callable可以返回值,但Runnable不能。 Callable可以抛出受控异常,但Runnable不能。 可调用对象可以与ExecutorService#invokeXXX(Collection<?扩展Callable<T>> tasks)方法,但Runnable不能。 可运行的{ 空运行(); } 可调用接口<V> { V call()抛出异常; }

请看这里的解释。

Callable接口类似于 可运行的,因为两者都是设计出来的 对于实例为的类 可能由另一个人执行 线程。然而,Runnable则不然 返回结果,且不能抛出 检查异常。