Java.util.currentExcutor,以及实现类中线程池和线程队列比较

核心和最大池大小
THREADPOOLEXECUTOR将自动调整池大小(参见GETPOOLSIZE()根据COREPOOLSIZE(参见设定的界限)GETCOREPOOLSIZE())和MAXIMUMPOOLSIZE(见GETMAXIMUMPOOLSIZE())。当在METHOD中提交新任务EXECUTE(JAVA.LANG.RUNNABLE)并且运行的线程数少于COREPOOLSIZE时,即使其他工作线程处于空闲状态,也会创建一个新线程来处理请求。如果运行的线程数大于COREPOOLSIZE但小于MAXIMUMPOOLSIZE,则仅在队列已满时才创建新线程。通过将COREPOOLSIZE和MAXIMUMPOOLSIZE设置为相同,可以创建固定大小的线程池。通过将MAXIMUMPOOLSIZE设置为本质上不受限制的值,例如INTEGER.MAX_VALUE,则允许池容纳任意数量的并发任务。最典型的是,核心和最大池大小仅在构造时设置,但也可以使用SETCOREPOOLSIZE(INT)和进行动态更改SETMAXIMUMPOOLSIZE(INT)。
按需施工
默认情况下,甚至仅在新任务需要时才创建并启动核心线程,但是可以使用METHOD PRESTARTCORETHREAD()或 来动态覆盖它PRESTARTALLCORETHREADS()。
创建新线程
使用创建新线程THREADFACTORY。如果未另行指定, EXECUTORS.DEFAULTTHREADFACTORY()则使用A,它将创建所有线程,并且所有线程都THREADGROUP具有相同的 NORM_PRIORITY优先级和非守护程序状态。通过提供不同的THREADFACTORY,可以更改线程的名称,线程组,优先级,守护程序状态等。如果在通过询问NEWTHREAD返回NULL来询问THREADFACTORY无法创建线程时,执行器将继续执行,但可能无法执行执行任何任务。
保活时间
如果当前池中有多个COREPOOLSIZE线程,则多余的线程将在空闲时间超过KEEPALIVETIME时终止(请参阅参考资料GETKEEPALIVETIME(JAVA.UTIL.CONCURRENT.TIMEUNIT))。当未积极使用池时,这提供了减少资源消耗的方法。如果池稍后变得更加活动,则将构建新线程。也可以使用METHOD动态更改此参数SETKEEPALIVETIME(LONG, JAVA.UTIL.CONCURRENT.TIMEUNIT)。使用LONG.MAX_VALUE 的值可以TIMEUNIT.NANOSECONDS 有效地使空闲线程永远不会在关闭之前终止

任何BlockingQueue都可以用于传输和保留提交的任务。此队列的使用与池大小交互:
•    如果运行的线程数少于corePoolSize,则执行程序总是喜欢添加新线程,而不是排队。
•    如果正在运行corePoolSize或更多线程,则执行程序总是更喜欢对请求进行排队,而不是添加新线程。
•    如果无法将请求排队,则将创建一个新线程,除非该线程超过了maximumPoolSize,在这种情况下,该任务将被拒绝。
有三种一般的排队策略:
1.    直接交接。对于工作队列,一个很好的默认选择是将SynchronousQueue任务移交给线程,而不用保留它们。在这里,如果没有立即可用的线程来运行任务,则尝试将任务排队的尝试将失败,因此将构造一个新线程。在处理可能具有内部依赖性的请求集时,此策略避免了锁定。直接切换通常需要无限制的maximumPoolSizes,以避免拒绝新提交的任务。反过来,当平均而言,命令继续以超出其处理速度的速度到达时,这可能会带来无限线程增长的可能性。
2.    无限队列。LinkedBlockingQueue在所有corePoolSize线程繁忙的情况下,使用无界队列(例如,没有预定义容量的队列)将导致新任务排队。因此,将仅创建corePoolSize线程。(因此,maximumPoolSize的值没有任何作用。)当每个任务完全独立于其他任务时,这可能是适当的,因此任务不会影响彼此的执行。例如,在网页服务器中。尽管这种排队方式对于消除短暂的请求突发很有用,但它承认当命令平均继续以比处理速度更快的速度到达时,工作队列将无限制地增长。
3.    有界队列。ArrayBlockingQueue当与有限的maximumPoolSizes一起使用时,有界队列(例如 )有助于防止资源耗尽,但调优和控制可能会更加困难。队列大小和最大池大小可能会相互折衷:使用大队列和小池可以最大程度地减少CPU使用率,操作系统资源和上下文切换开销,但会导致人为地降低吞吐量。如果任务频繁阻塞(例如,如果它们受I / O限制),则系统可能能够安排比您原先允许的线程更多的时间。使用小队列通常需要更大的池大小,这会使CPU繁忙,但可能会遇到不可接受的调度开销,这也会降低吞吐量。

 

posted @ 2019-09-26 16:05  活泼的大白兔  阅读(210)  评论(0编辑  收藏  举报