微信技术群:Day9884125
package com.manage.common.util;
import java.util.concurrent.*;
/**
* 线程池
* @author duaiyu
* @version V1.0
* @date 2022/5/15
* 来源:自研
*/
public class ThreadPoolUtil {
/**
* 线程池的实现
* 线程池不建议使用Executors,Executors可以创建一个固定池大小的线程池,它的任务队列是无界的。
* 任务队列无界的坏处就是,通过他创建的,固定池大小设置成了100,200.这时候因为它的任务队列无界,
* 他就会贪得无厌,只要来任务了,就往里面放。这时候的问题就是,任务太多了,已经超出了能够处理笑话的程度了,
* 但是又不报错,这时候任务在里面久久得不到执行。这就是阿里不允许使用的原因。
*
* api实现的四个线程池不建议使用的原因,小编不做介绍,大家自行百度了解
* 这里实现ThreadPoolExecutor是建议使用的
*/
public Object threadPoolExecutor(Runnable tasks){
/**
* 参数信息:
* int corePoolSize 核心线程大小
* int maximumPoolSize 线程池最大容量大小
* long keepAliveTime 线程空闲时,线程存活的时间
* TimeUnit unit 时间单位
* BlockingQueue<Runnable> workQueue 任务队列。一个阻塞队列
*
* 任务队列的三种方式:
* 1 直接提交策略
* 工作队列的默认选项是 SynchronousQueue,它将任务直接提交给线程而不保持它们。
* 在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。
* 此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes
* 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
* SynchronousQueue是无界的,也就是说他存数任务的能力是没有限制的,但是由于该Queue本身的特性,
* 在某次添加元素后必须等待其他线程取走后才能继续添加。
*
* 2 无界队列
* 使用无界队列(例如,不具有预定义容量的 LinkedBlockingQueue)将导致在所有 corePoolSize
* 线程都忙时新任务在队列中等待。这样,创建的线程就不会超过 corePoolSize。(因此,maximumPoolSize的值
* 也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;例如,
* 在 Web页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,
* 此策略允许无界线程具有增长的可能性。
* LinkedBlockingQueue是大小不固定的BlockingQueue,若其构造时指定大小,生成的BlockingQueue有
* 大小限制,不指定大小,其大小有Integer.MAX_VALUE来决定。其所含的对象是FIFO顺序排序的。
* PriorityBlockingQueue类似于LinkedBlockingQueue,但是其所含对象的排序不是FIFO,
* 而是依据对象的自然顺序或者构造函数的Comparator决定。
*
* 3 有界队列
* 当使用有限的 maximumPoolSizes时,有界队列(如 ArrayBlockingQueue)有助于防止资源耗尽,
* 但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低
* CPU使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,
* 如果它们是 I/O边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,
* CPU使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量。
*
* 拒绝策略
* 1 AbortPolicy 直接抛出异常
* 2 DiscardPolicy 放弃当前任务,并且不会抛出任何异常
* 3 DiscardOldestPolicy 会将队列中最早添加的元素移除,
* 再尝试添加,如果失败则按该策略不断重试
* 4 CallerRunsPolicy 由调用线程(提交任务的线程)处理该任务,
* 如果调用线程是主线程,那么主线程会调用执行器中的execute方法来
* 执行改任务
*/
ThreadPoolExecutor thread = new ThreadPoolExecutor(10,20,
3, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1024),
new ThreadPoolExecutor.AbortPolicy());
Object result = "";
try{
// 执行任务
Future future = thread.submit(tasks);
// 查看执行情况,有异常会在此显示
result = future.get();
}catch (InterruptedException e){
e.printStackTrace();
}catch (ExecutionException e){
e.printStackTrace();
}finally {
thread.shutdown();
}
return result;
}
}