Java线程池深度解析:原理、拒绝策略与最佳实践
版权申诉
51 浏览量
更新于2024-07-19
收藏 1.69MB DOCX 举报
"这篇学习资料深入探讨了Java线程池的相关知识,涵盖了线程池的原理、Future模式的实现机制、execute与submit方法的区别、SynchronousQueue的工作方式、拒绝策略,以及线程池在实际使用中可能遇到的问题和解决方案。此外,资料还涉及到了线程池的参数设置、Tomcat和Netty自定义线程池的原因,以及异常处理策略。"
1:线程池原理
线程池通过维护一组可重用的工作线程来提高程序性能,避免频繁创建和销毁线程的开销。在Java中,`ThreadPoolExecutor`是实现线程池的核心类。线程池中的线程通过一个无限循环来接收并执行任务,当线程执行异常时,异常会被捕获并抛出,导致线程终止,同时线程从工作集合中移除。
2:Future模式get()和get(timeout)实现
Future模式提供了一种异步计算的结果获取方式。`get()`和`get(timeout)`方法会在调用者线程阻塞,直到任务完成或达到指定超时时间。当任务完成后,调用者可以获取结果。
3:execute与submit方法区别
`execute()`方法用于提交`Runnable`任务,而`submit()`方法可以提交`Callable`任务,返回一个`Future`对象,使得我们能查询任务状态和获取结果。`submit()`内部实际上是将`Callable`包装成`FutureTask`,再调用`execute()`。
4:SynchronousQueue
SynchronousQueue是一个特殊的阻塞队列,它不存储元素,任务的提交必须立即有另一个线程来接手。如果无法找到接手线程,任务提交会失败。
5:拒绝策略
`CallerRunsPolicy`是线程池的一种拒绝策略,当线程池无法处理新任务时,会由调用`execute`的线程来执行这个任务,以此来控制任务的提交速度。
6:线程池的主要参数
线程池的主要参数包括核心线程数(`corePoolSize`)、最大线程数(`maximumPoolSize`)、线程存活时间(`keepAliveTime`)和工作队列(`WorkQueue`)。
7:线程池默认线程及核心线程数
线程池创建时,默认线程数取决于实现,通常为0。如果核心线程数为10且达到,即使在保持存活时间后,只要仍有任务提交,核心线程数不会减少。除非显式调用`setCorePoolSize(0)`。
8:Tomcat自定义线程池原因
Tomcat使用自定义线程池是因为JDK自带的线程池可能无法满足其特定需求,如更精细的线程管理、更好的性能优化或与Servlet容器的集成。
9:ThreadPoolExecutor与ExecutorCompletionService的区别
`ExecutorCompletionService`是一个辅助类,它结合了`Executor`和`Future`,使得批量异步任务可以按完成顺序处理结果,而`ThreadPoolExecutor`则专注于任务的执行。
10:线程池异常处理
线程池中的线程如果抛出异常,对于`execute`提交的任务,异常会被丢弃,线程继续执行下一个任务。而对于`submit`提交的任务,异常会封装在`Future`的`get`方法中抛出。异常线程不会直接影响其他线程,但可能会导致线程池的拒绝策略被触发。
11:Netty不使用JDK Future
Netty选择不使用JDK的`Future`主要是因为Netty的异步模型更加强大和灵活,它使用了自己的`ChannelFuture`和`Promise`,这些类提供了更丰富的功能,如链式调用和事件通知。
2023-06-24 上传
2023-06-09 上传
2023-03-29 上传
2024-11-11 上传
2024-11-11 上传
2024-11-11 上传
2024-10-30 上传