一、shutdown()
和shutdownNow()
的区别
shutdown()
和shutdownNow()
是ExecutorService
接口中用于关闭线程池的方法。
-
shutdown()
: 当调用shutdown()
方法时,线程池会停止接受新任务,并允许已经提交的任务继续执行,直到所有任务完成。它会平滑关闭线程池,等待已提交的任务执行完成,不再接受新任务。这意味着将不再有新的任务被提交,但线程池中的线程会继续执行已提交的任务,直到完成。 -
shutdownNow()
: 当调用shutdownNow()
方法时,线程池会停止接受新任务,并尝试中断正在执行的任务。它会立即关闭线程池,不再等待正在执行的任务完成,正在执行的任务会被中断,同时返回尚未执行的任务列表。我们可以通过返回的任务列表来获取未执行的任务,然后进行后续处理。
总结区别:
shutdown()
方法会禁止提交新任务,但允许已提交的任务执行完毕,然后关闭线程池,无返回值。shutdownNow()
方法会禁止提交新任务,并尝试中断正在执行的任务,然后立即关闭线程池,会返回未执行的任务列表。
需要注意的是,这两个方法都不会阻塞主线程,即它们的调用后立即返回。如果希望等待线程池中的任务执行完毕,可以使用awaitTermination()
方法来等待一段时间,或者通过查看isTerminated()
方法来判断线程池是否已经完全关闭。
二、 submit()
和execute()
的区别
submit()
和execute()
都是用于在线程池中提交任务的方法,但它们在一些方面有所不同。
-
返回值类型:
submit()
方法返回一个Future
对象,可以用于获取任务的执行结果或取消任务。execute()
方法没有返回值。
-
异常处理:
submit()
方法可以通过Future
对象的get()
方法来获取任务执行过程中抛出的异常,并进行处理。execute()
方法没有直接获取任务异常的机制,因此需要在任务内部进行异常处理。
-
接收任务类型:
submit()
方法可以接收Runnable
和Callable
类型的任务。execute()
方法只能接收Runnable
类型的任务。
-
阻塞与非阻塞:
submit()
方法是阻塞的,调用线程会等待任务执行完成,并返回任务的执行结果。execute()
方法是非阻塞的,调用线程不会等待任务执行完成,而是立即返回。
-
取消任务:
submit()
方法返回的Future
对象可以使用cancel()
方法来取消任务的执行。execute()
方法没有直接取消任务的方法,需要通过其他方式来实现任务的取消。
总结:
- 如果需要获取任务的执行结果、处理任务的异常或者取消任务的执行,可以使用
submit()
方法。 - 如果只是简单地提交任务给线程池执行,并不关心任务的返回结果,可以使用
execute()
方法。