配置ThreadPoolExecutor
[本文是我对Java Concurrency In Practice C08的归纳和总结. ?转载请注明作者和出处, ?如有谬误, 欢迎在评论中指正. ]
Executors的静态方法newCachedThreadPool, newFixedThreadPool, newScheduledThreadPool所返回的线程池都是ThreadPoolExecutor对象或者其子类对象. ThreadPoolExecutor提供了多种配置, 可以根据实际定制合适的线程池.
?
线程的创建和销毁
ThreadPoolExecutor构造函数中的corePoolSize, maximumPoolSize, keepAliveTime参数与线程的创建和销毁相关.?
corePoolSize指定ThreadPoolExecutor中持有的核心线程数, 除非task队列已满, ThreadPoolExecutor不会创建超过核心线程数的线程(corePoolSize为0时是一种特殊情况, 此时就算task队列没有饱和, 向线程池第一次提交task时仍然会创建新的线程), 核心线程一旦创建就不会销毁, 除非设置了allowCoreThreadTimeOut(true), 或者关闭线程池.
maximumPoolSize指定线程池中持有的最大线程数. 对于超过核心线程数的线程, 如果在指定的超时时间内没有使用到, 就会被销毁.
keepAliveTime指定超时时间.
Executors类的静态方法创建线程池的源码:
?
扩展ThreadPoolExecutor
ThreadPoolExecutor类提供了多个"钩子"方法, 以供其子类实现, 比如beforeExecute, afterExecute, terminated等. 所谓"钩子"是指基类预留的, 但是没有提供具体实现的方法, 其方法体为空. 子类可以根据需要为"钩子"提供具体实现.
beforeExecute和afterExecute方法分别在执行task前后调用:
private void runTask(Runnable task) {final ReentrantLock runLock = this.runLock;runLock.lock();try {if (runState < STOP && Thread.interrupted() && runState >= STOP)thread.interrupt();boolean ran = false;beforeExecute(thread, task);try {task.run();ran = true;afterExecute(task, null);++completedTasks;} catch (RuntimeException ex) {if (!ran)afterExecute(task, ex);throw ex;}} finally {runLock.unlock();}}?beforeExecute和afterExecute方法可以用于记录日志, 统计数据等操作.
terminated方法在线程池被关闭后调用. terminated方法可以用于释放线程池申请的资源.
?