Java线程池深度解析:ThreadPoolExecutor与源码分析

需积分: 0 0 下载量 75 浏览量 更新于2024-08-04 收藏 891KB PDF 举报
"线程池ThreadPoolExecutor的源码分析及使用方法" 在Java编程中,线程池是一种管理线程的高效工具,它允许开发者控制并发执行的任务数量,避免了频繁创建和销毁线程带来的开销。ThreadPoolExecutor是Java并发包(java.util.concurrent)中的核心类,用于创建和管理线程池。 ### 创建线程的方式 1. **继承Thread类**:创建一个新类继承自Thread类,重写run方法,然后创建该类的实例并调用start方法启动线程。这种方式限制了单继承性,不利于代码复用。 2. **实现Runnable接口**:创建一个类实现Runnable接口,重写run方法,然后将Runnable对象作为参数传递给Thread的构造器。这样可以避免单继承问题,但本质上仍然是基于Thread类来执行。 3. **实现Callable接口**:Callable接口与Runnable类似,但其call方法可以有返回值并能抛出异常。要执行Callable任务,需将其包装在FutureTask中,然后提交给Executor执行。 ### Executors与线程池 Java提供Executors类来创建线程池,主要有以下几种线程池类型: - **newFixedThreadPool**:固定大小的线程池,线程数量不变,超出的请求会被阻塞。 - **newSingleThreadExecutor**:只有一个工作线程的线程池,保证任务顺序执行。 - **newCachedThreadPool**:缓存线程池,会创建大量线程,当线程空闲时间超过60秒则销毁,适合短期异步任务。 - **newScheduledThreadPool**:调度线程池,可以定时或延迟执行任务。 线程池的核心在于`ThreadPoolExecutor`,它有7个关键参数: 1. **corePoolSize**:核心线程数,即使无任务也会保持这些线程不被销毁。 2. **maximumPoolSize**:最大线程数,超过核心线程数时,新建线程处理任务。 3. **keepAliveTime**:非核心线程空闲时间,超过这个时间会销毁非核心线程。 4. **unit**:keepAliveTime的时间单位。 5. **workQueue**:任务队列,存放待执行的任务。 6. **threadFactory**:创建线程的工厂,可以定制线程属性。 7. **handler**:拒绝策略,当线程池和队列都满时,如何处理新任务。 ### ThreadPoolExecutor的工作流程 1. 当提交任务到线程池时,首先会尝试将任务放入任务队列。 2. 如果队列已满,且当前线程数小于核心线程数,那么创建新的核心线程执行任务。 3. 如果当前线程数等于或超过核心线程数,且队列已满,会创建非核心线程执行任务,直到达到最大线程数。 4. 当达到最大线程数且队列已满,根据拒绝策略处理新任务。 理解并正确配置这些参数对于优化线程池性能至关重要,可以避免资源浪费,提高系统效率。在实际开发中,通常建议根据具体业务需求手动创建线程池,以便更好地控制线程资源。 在`CallableTest`示例中,实现了Callable接口的类`CallableTest`返回一个整数,这表明任务执行后可以获取结果。通过`ExecutorService`的`submit`方法提交Callable任务,结果可以通过Future的`get`方法获取。这种方式更加灵活,适用于需要返回结果的异步计算场景。