ThreadPoolExecutor和ThreadPoolTaskExecutor
-
ThreadPoolExecutor
1:这个类是JDK中的线程池类,继承自Executor, Executor 顾名思义是专门用来处理多线程相关的一个接口,所有线程相关的类都实现了这个接口,里面有一个execute()方法,用来执行线程,线程池主要提供一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁的额外开销,提高了响应的速度
2:ExecutorService为线程池接口,提供了线程池生命周期方法,继承自Executor接口,ThreadPoolExecutor为线程池实现类,提供了线程池的维护操作等相关方法,继承自AbstractExecutorService,AbstractExecutorService实现了ExecutorService接口。 ``` 3:当然,我们也可以直接new ThreadPoolExecutor的构造方法来创建线程池,传入需要的参数。 ```
-
ThreadPoolTaskExecutor
1:这个类则是spring包下的,是sring为我们提供的线程池类,可以使用基于xml配置的方式创建
<!-- spring线程池 --> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 核心线程数 --> <property name="corePoolSize" value="10"/> <!-- 最大线程数 --> <property name="maxPoolSize" value="200"/> <!-- 队列最大长度 >=mainExecutor.maxSize --> <property name="queueCapacity" value="10"/> <!-- 线程池维护线程所允许的空闲时间 --> <property name="keepAliveSeconds" value="20"/> <!-- 线程池对拒绝任务(无线程可用)的处理策略 --> <property name="rejectedExecutionHandler"> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/> </property> </bean>
然后通过自动注入的方式注入线程池,
@Resource(name="taskExecutor") ThreadPoolTaskExecutor taskExecutor; // 或者可以直接@Autowried @AutoWired ThreadPoolTaskExecutor taskExecutor
或者是通过配置类的方式配置线程池,然后注入。
package com.sinosig.sl.sssc.base.threadconfig; import com.sinosig.sl.sssc.base.threadfactory.AuditThreadFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; @Configuration @EnableAsync public class ThreadConfig { //Runtime.getRuntime().availableProcessors() 获取CPU的核心数 public static final int MAXIMUM_POOLSIZE = Runtime.getRuntime().availableProcessors() + 1; public static final int CORE_POOLSIZE = Runtime.getRuntime().availableProcessors() / 2 + 1; public static final int DEFAULT_CAPACITY = 1000; //999个四级机构,最多不超过1000 @Bean("auditThreadConfig") public Executor getAuditThreadConfig() { ThreadFactory threadFactory = new AuditThreadFactory("FeePay"); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(CORE_POOLSIZE);//核心线程数 executor.setMaxPoolSize(MAXIMUM_POOLSIZE);//最大线程数 executor.setThreadFactory(threadFactory);//线程前缀名称 executor.setKeepAliveSeconds(30);//线程空闲时间 executor.setQueueCapacity(DEFAULT_CAPACITY);//队列程度 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); //采取抛异常拒绝策略 // 拒绝策略 // // rejectedExectutionHandler参数字段用于配置绝策略,常用拒绝策略如下 // // AbortPolicy:用于被拒绝任务的处理程序,它将抛出RejectedExecutionException // // CallerRunsPolicy:用于被拒绝任务的处理程序,它直接在execute方法的调用线程中运行被拒绝的任务。 // // DiscardOldestPolicy:用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试execute。 // // DiscardPolicy:用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。 executor.initialize(); return executor; } }
处理流程
1.查看核心线程池是否已满,不满就创建一条线程执行任务,否则执行第二步。 2.查看任务队列是否已满,不满就将任务存储在任务队列中,否则执行第三步。 3.查看线程池是否已满,即就是是否达到最大线程池数,不满就创建一条线程执行任务,否则就按照策略处理无法执行的任务。
测试方法
写一个demo类,标注@Async的方法为异步方法,然后交给spring管理,然后controller for循环调用这个方法,日志截图: