如果返回值与我无关,我应该如何在ExecutorService的提交或执行之间做出选择?

如果我对两者都进行测试,除了返回值之外,我没有看到两者之间有任何差异。

ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.execute(new Task());

ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.submit(new Task());

当前回答

来自Javadoc:

该命令可以在新线程、池线程或调用线程中执行,由Executor实现自行决定。

因此,根据Executor的实现,您可能会发现提交线程在任务执行时阻塞。

其他回答

只是在公认的答案上加上

然而,从任务抛出的异常使其变为未捕获 仅用于使用execute()提交的任务的异常处理程序;为任务 使用submit()提交给执行器服务,任何抛出的异常 被认为是任务返回状态的一部分。

如果你不关心返回类型,使用execute。它和submit一样,只是没有Future的返回。

来自Javadoc:

该命令可以在新线程、池线程或调用线程中执行,由Executor实现自行决定。

因此,根据Executor的实现,您可能会发现提交线程在任务执行时阻塞。

摘自Javadoc:

方法submit通过创建和扩展基方法{@link Executor#execute} 返回一个{@link Future},可用于取消执行和/或等待 完成。

就我个人而言,我更喜欢使用execute,因为它感觉更具有声明性,尽管这确实是个人偏好的问题。

为了提供更多信息:在ExecutorService实现的情况下,通过调用Executors.newSingleThreadedExecutor()返回的核心实现是一个ThreadPoolExecutor。

提交调用由其父AbstractExecutorService提供,所有调用都在内部执行。execute由ThreadPoolExecutor直接覆盖/提供。

在异常/错误处理方面有区别。

使用execute()排队的任务生成一些Throwable,将导致运行该任务的线程的UncaughtExceptionHandler被调用。默认的UncaughtExceptionHandler,它通常将Throwable堆栈跟踪打印到System。如果没有安装自定义处理程序,则将调用。

另一方面,由使用submit()排队的任务生成的Throwable将绑定到调用submit()生成的Future。在该Future上调用get()将抛出一个ExecutionException,其原因为原始Throwable(通过在ExecutionException上调用getCause()来访问)。