在看开源代码的时候,发现ExecutorService类的子类提交异步任务有两种方式,但不太了解它们的区别,于是便阅读一下jdk源码学习一番。
`ExecutorService` 是 Java 提供的用于管理和执行线程任务的接口。`execute()` 方法和 `submit()` 方法是 `ExecutorService` 接口中的两种常用方法,它们的区别如下:
1. 返回值类型:`execute()` 方法没有返回值,因此无法获取任务执行的结果;而 `submit()` 方法返回一个 `Future` 对象,通过该对象可以获取任务执行的结果。
2. 异常处理:`execute()` 方法无法处理任务执行过程中抛出的异常,异常将会被传递给调用方处理;而 `submit()` 方法可以通过调用 `Future.get()` 方法来获取任务执行的结果,并且在方法中可以捕获并处理任务执行过程中的异常。
3. 任务提交方式:`execute()` 方法只能接收 `Runnable` 对象,即无返回值的任务;而 `submit()` 方法既可以接收 `Runnable` 对象,也可以接收 `Callable` 对象,即有返回值的任务。
综上所述,`execute()` 方法适用于简单的异步任务执行,不需要关注任务的执行结果和异常处理;而`submit()` 方法更加灵活,可以提交有返回值的任务,并且能够处理任务执行过程中的异常情况。根据具体的业务需求,选择合适的方法来提交和执行任务。
在AbstractExecutorService类里面,可以看到submit的实现:
```java
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
```
可以看到这种方式提交任务,最终也是通过调用`execute()` 方法的。因此,当我们使用ExecutorService提交定时任务的时候,如果不关注返回值的话,都用`execute()`比较好理解点。