ThreadPoolExecutor会根据你设置的核心线程数和最大线程数来调整线程池的大小。
举个栗子:
默认情况下,核心线程只有当任务提交到threadPoolExecutor时才会创建,但其实也可以通过调用以下方法来动态创建核心线程:
举个栗子 如果你初始化线程池时使用非空的任务队列(队列中已经有了一些任务),可以使用上述方法提前初始化线程池中的线程
线程都是使用 ThreadFactory 创建的。如果没有特别指定自定义的ThreadFactory,默认使用Executors.defaultThreadFactory(),这样所有的线程都属于同一个ThreadGroup,而且所有线程都有相同的优先级,而且都不是守护线程。如果提供一个自定义的ThreadFactory,你可以修改线程名,thread group,优先级和守护线程标志。如果ThreadFacotry创建线程失败并且返回了null,threadPoolExecutor不会报错,但是不会执行任务。
下面一段英文我没有很好地理解,有大神看到可以解答一下 Threads should possess the "modifyThread" RuntimePermission. If worker threads or other threads using the pool do not possess this permission, service may be degraded: configuration changes may not take effect in a timely manner, and a shutdown pool may remain in a state in which termination is possible but not completed.
暂时先这样翻译:
线程必须要处理 "modifyThread" RuntimePermission。如果池中的工作线程或其他线程无法处理这种权限,服务可能会被降级:配置变更可能不会被及时处理,而且一个线程池可能一直保持着关闭中的状态。
如果池中线程数大于核心线程数,那么多余的线程在他们空闲时间大于keepAliveTime时会被销毁。这其实就是在系统压力很低的情况下节省资源啦。如果以后线程池后面又接了新任务,新的线程也会再次被创建。这个参数也可以通过setter方法来动态设置。如果你将keepAliveTime设置成Long.MAX_VALUE就等于禁用了次参数。默认情况下,线程的过期时间只有在线程数大于核心线程数时才会起作用。但是allowCoreThreadTimeOut(boolean)可以将keepAliveTime也设置为对核心线程数有效。
任意一个阻塞队列都可以用来保存提交到线程池的任务。队列的使用效果和线程大小是相关联的,如下所示:
如果线程池已经关闭、或者线程池使用了有限的最大线程数或有界队列,而且已经满了,那么新的任务会被拒绝。在这两种情况下,execute方法会调用RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor)来处理被拒绝的请求,以下四种处理器已经被预先定义好:
丢弃策略RejectedExecutionHandler是可以自定义的,针对特定场景,我们可以自己设计在特定场景下的丢弃策略
所谓Hook(钩子)方法,就是一个类预留了几个方法给子类重写,方便子类做一些自定义的操作。可以理解为父类就是一个窗帘杆,子类就是窗帘,窗帘杆上的钩子我已经给你留好了,你只要把窗帘上的环挂上去就能用
ThreadPoolExecutor提供了可被子类重写的beforeExecute(Thread, Runnable) 和 afterExecute(Runnable, Throwable) 方法。这两个方法用来做一些预处理操作,例如初始化TheadLocal变量,做一些统计,打打日志。 terminated()方法也可以被重写,当ThreadPoolExecutor被终止时可以做一些处理。如果hook或者callback方法抛出了一些异常,内部的工作线程可能会失败并且突然终止。