对线面试官 - 线程池 (二)
面试官:线程池有哪些执行方法?
派大星:线程池有两种执行方法,分别是 execute()和 submit()。
面试官:那么 execute()和 submit()有什么区别呢?
派大星:从提交的任务类型角度来看,execute()只能提交 Runnable 类型的任务,而 submit()既能提交 Runnable 类型的任务,也能提交 Callable 类型的任务。此外,从 API 层面理解,execute()是在 Executor 接口中定义的,而 submit()方法是在 ExecutorService 接口中定义的,具体的实现是由 AbstractExecutorService 进行。
面试官:那么 execute()和 submit()在异常处理方面有什么区别吗?
派大星:execute()会直接抛出任务执行时的异常,可以使用 try catch 来捕获,和普通线程的处理方式完全一致。而 submit()会吃掉异常,可以通过 Future 的 get 方法将任务执行时的异常重新抛出。
面试官:那么 execute()和 submit()的返回值有什么区别呢?
派大星:execute()没有返回值,而 submit()有返回值。
面试官:从 API 层面来看,execute 方法和 submit 方法的实现有什么不同呢?
派大星:
execute 是在 Executor 接口中定义的。ThreadPoolExecutor()中并没有定义,但是 ThreadPoolExecutor 类继承了 AbstractExecutorService 抽象类,而该抽象类实现了 ExecutorService 接口,ExecutorService 接口又继承了 Executor 接口。总结:也就是说 ThreadPoolExecutor 实现了 execute()方法,
具体来说,AbstractExecutorService 类中 submit 方法被重载了三次,分别接受 Runnable、Callable 和 Runnable 和 ResultHandler 类型的参数。而 ThreadPoolExecutor 类中只实现了接受 Runnable 类型参数的 execute 方法。另外,submit 方法会返回一个 Future 对象,而 execute 方法没有返回值。
面试官:那么如果我不需要一个结果,直接用 execute()会有什么好处吗?
派大星:如果提交的任务不需要一个结果的话直接用 execute()会提高性能。因为 submit()底层调用的时候,又将任务交给了 execute()方法。
面试官:派大星,你能否再详细解释一下为什么说如果提交的任务不需要一个结果的话直接用 execute()会提高性能呢?
派大星:当我们使用 submit()方法提交任务时,会返回一个 Future 对象,通过这个对象我们可以在任务执行完毕后获取执行结果。而 execute()方法不会返回这个 Future 对象,所以如果我们提交的任务不需要一个结果,直接使用 execute()方法,就可以避免创建这个 Future 对象,从而提高性能。因为创建和管理这个 Future 对象也会带来一定的开销。
面试官:非常好的解释,那如果我提交的任务需要一个结果,使用 submit()方法和 execute()方法有什么区别呢?
派大星:如果提交的任务需要一个结果,那么使用 submit()方法是比较好的选择,因为它会返回一个 Future 对象,我们可以通过这个对象在任务执行完毕后获取执行结果。而使用 execute()方法提交任务时,我们需要自己通过其他方式来获取任务执行结果,比如使用共享变量或者使用回调函数等方式。
如有问题,欢迎加微信交流:32479732,或关注微信公众号【码上遇见你】。
版权声明: 本文为 InfoQ 作者【派大星】的原创文章。
原文链接:【http://xie.infoq.cn/article/1e7a25e3bf869e106f756b0c7】。
本文遵守【CC BY-NC-ND】协议,转载请保留原文出处及本版权声明。
评论