线程池与策略介绍
//1 直接提交队列: // SynchronousQueue:直接传递。对于一个好的默认的工作队列选择是SynchronousQueue,该队列传递任务到线程而不持有它们。
内部不存储元素,可认为是容量为 0 的特殊队列,仅作为生产者和消费者的同步媒介。当处理那些内部依赖的任务集合时,这个选择可以避免锁住。 // 直接接传递通常需要无边界的最大线程数来避免新提交任务被拒绝处理。 // 当任务以平均快于被处理的速度提交到线程池时,它依次地确认无边界线程增长的可能性; //2 无界的任务队列 // LinkedBlockingQueue:无界队列可以指定初始容量大小,这个队列排列元素FIFO(先进先出)。 Integer.MAX_VALUE 没有预先定义容量的无界队列,在核心线程数都繁忙的时候会使新提交的任务在队列中等待被执行, // 所以将不会创建更多的线程,因此,最大线程数的值将不起作用。当每个任务之间是相互独立的时比较适合该队列,所以任务之间不能互相影响执行。例如,在一个WEB页面服务器, // 当平滑的出现短暂的请求爆发时这个类型的队列是非常有用的,当任务以快于平均处理速度被提交时该队列会确认无边界队列增长的可能性。 //3有界的任务队列 // ArrayBlockingQueue:有界阻塞队列,遵循FIFO原则,一旦创建容量不能改变,基于数组实现,创建时需指定固定容量,之后无法更改,其内部通过双指针标识队列的头和尾. // 当线程池使用有限的最大线程数时该队列可以帮助保护资源枯竭,但它更难协调和控制。队列大小和最大线程数在性能上可以互相交换: // 使用大队列和小线程池会降低CPU使用和OS资源与上下文切换开销,但会导致人为降低吞吐量,如果任务频繁阻塞,系统的线程调度时间会超过我们的允许值; // 如果使用小队列大池,这将会使CPU较为繁忙但会出现难以接受的调度开销,这也会导致降低吞吐量 //4优先任务队列
// 优先任务队列通过PriorityBlockingQueue实现
//cpu的数量
System.out.println(Runtime.getRuntime().availableProcessors());
// 构造方法
// Constructor and Description
//核心线程池大小 最大线程池大小 等待时间 等待时间单位 工作队列
// ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
// 创建一个新的 ThreadPoolExecutor与给定的初始参数和默认线程工厂和拒绝执行处理程序。 //核心线程池大小 最大线程池大小 等待时间 等待时间单位 工作队列 拒绝策略
// ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
// 创建一个新的 ThreadPoolExecutor与给定的初始参数和默认线程工厂。
//核心线程池大小 最大线程池大小 等待时间 等待时间单位 工作队列 线程工厂
// ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
// 创建一个新的 ThreadPoolExecutor与给定的初始参数和默认拒绝执行处理程序。
//核心线程池大小 最大线程池大小 等待时间 等待时间单位 工作队列 线程工厂
// ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
// 创建一个新 ThreadPoolExecutor给定的初始参数。
//策略
// 拒绝策略AbortPolicy:丢弃任务并抛出RejectedExecutionException
// CallerRunsPolicy:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。
// DiscardOldestPolicy:丢弃队列中最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。
// DiscardPolicy:丢弃任务,不做任何处理。
阻塞特性 ArrayBlockingQueue:当队列满时,生产者线程插入元素会阻塞;队列为空时,消费者线程获取元素会阻塞. LinkedBlockingQueue:有界时,队列满则生产者阻塞,队列为空则消费者阻塞;无界时,生产者一般不会阻塞,但消费者队列为空时会阻塞. SynchronousQueue:插入操作必须等待相应的删除操作,反之亦然,若没有匹配的操作则阻
并发性能 ArrayBlockingQueue:读写操作使用同一把锁,在高并发的生产者和消费者场景下,性能相对较差. LinkedBlockingQueue:读写操作分别使用独立的锁,允许生产者和消费者并行操作,并发性能更好. SynchronousQueue:性能取决于生产者和消费者的匹配速度,在一对一的简单同步场景下,性能表现出色
适用场景 ArrayBlockingQueue:适用于任务量有限且已知的场景,可根据需求设置容量来控制系统资源使用,常用于实现任务调度、生产者 - 消费者模型中的缓冲等功能. LinkedBlockingQueue:适用于任务量不断增加且无明确上限的场景,能无限制添加任务,但需注意内存管理,常用于处理瞬态突发请求等. SynchronousQueue:适用于任务执行和处理需严格同步的场景,如一个生产者对应一个消费者的情况,可避免任务排队等待,提高响应速度
AbortPolicy:直接抛出异常,这是默认策略; CallerRunsPolicy:用调用者所在的线程来执行任务; DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务; DiscardPolicy:直接丢弃任务;
本文来自博客园,作者:余生请多指教ANT,转载请注明原文链接:https://www.cnblogs.com/wangbiaohistory/p/15100197.html

浙公网安备 33010602011771号