在以往写程序时并没有多线程的概念,导致程序运行时效率极低,于是抽时间去学习了以下线程池的相关概念,废话不多说马上开始
线程:
线程是进程的一部分,一个进程是一个程序,一个进程是由多个线程组成。
线程池:
通常写线程代码时,往往在一段任务执行时,会创建线程,在任务结束时会销毁线程。这和生活中的一次性筷子相似,用了一次就扔,下次要用再买。会造成大量的浪费(环保)。所以通常人家家里都会有许多的木质筷子,吃好饭就放回去,下次吃饭时再拿出来,不会造成浪费。
线程池也是一样的,在任务执行时,创建一个线程(买了一双筷子),任务开始时(使用筷子吃饭),任务结束时(将筷子收在厨房)放回线程池里方便下次继续使用。这就是线程池的功能
线程池参数
尽量不要使用内置的线程池,会发生一些不可预计的错误。
@Configuration
@EnableAsync
public class MyThread {
private int corePoolSize = 30;//线程池运行线程数(厨房一共买了多少双筷子)
private int maxPoolSize = 80;//线程池维护线程的最大数量(放筷子的篮子里最多能放多少双筷子)
private int queueCapacity = 40; //队列(现在买的筷子不够用,得多买一些)
private Long keepAlive = 60L;//允许的空闲时间(每一双筷子空闲的时间)
@Bean
public ThreadPoolExecutor taskExecutor() {
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(corePoolSize,
maxPoolSize,
keepAlive,
TimeUnit.SECONDS,
new ArrayBlockingQueue(queueCapacity));
return poolExecutor;
}
}
首先
核心线程数:线程池内有正在运行的线程数量,这些线程永远不会被回收
线程池大小:线程池最多存放多少个线程
线程工厂:线程池中的线程都是通过这个工厂创建的。
任务拒绝执行策略:当线程池无法处理新来任务时的处理策略。
任务队列:当正在运行的线程满了时又有新任务加进来的话线程没有空闲,就把任务存放在队列中,线程空闲了一个就去队列中拿任务执行(队列大小),当队列也被任务塞满时,线程工厂会创建一个新线程执行任务
keepAliveTime:当线程池中线程数量大于corePoolSize时,闲置线程最长可以存活的时间。超过了这个时间后线程会被回收
闲置线程的产生是由于任务过多,超出了队列导致线程工厂创建新线程执行任务,任务完成后线程会空闲下来。
线程池的运行流程
当一个任务被提交到线程池时,线程池中线程数量少于核心线程数就创建一个线程……,直到创建的线程数等于核心线程数后,就不再创建线程。之后新来的任务就一直被执行,如果一个时间有大量的任务被提交到线程池中,核心线程已经全部都在执行任务,那么这些任务就会被放进任务队列中,等待线程运行,如果任务队列也被塞满了,那么线程工厂就会创建临时线程去执行任务,当每个任务都很耗时间,总线程数等于了最大线程数,那么这时,新提交的任务会根据任务的拒绝策略被处理。
当任务全部处理完成后,根据配置的线程空闲时间,临时线程会被回收。而核心线程不会被回收,除非人为的配置过。