线程池记录

it2024-03-29  50

线程池集成关系,以及创建线程池构造参数说明

1:Executor—>ExecutorService—>AbstractExecutorService—>ThreadPoolExecutor 创建线程池是通过ThreadPoolExecutor 创建的

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

参数1: 核心线程数 参数2: 线程总数(一定要大于或者等于核心线程数)线程总数=核心线程数+非核心线程数; 参数3/参数4: 表示非核心线程数的超时时间 超过时间过了就会回收非核心线程 核心线程不会被回收这样做为了节约性能; 参数5: 存放Runnable的容器一般为队列或者链表数据结构; 参数6: 用线程工厂创建的线程,可以设置线程是否为守护线程和线程的名字,方便排查问题 参数7: 饱和策略,如果要执行的任务(Runnable)数量过多大于了最大线程数就会执行饱和策略,默认是抛出异常;

Executor.execute(Runnable) 如果线程池中的线程数<核心线程数 那么就会创建核心线程数,核心线程数是不会被回收的;如果线程数>=核心线程 那么就会把线程放入任务队列中,线程池中的空闲线程就会去任务队列中取出任务来执行,如果任务队列也满了还有要执行的任务并且目前线程池中的线程 数没有超过最大线程数的时候就会创建非核心线程去执行任务;如果线程中达到了最大线程数并且还调用executor(Runnable) 那就执行饱和策略; ps:需要执行的Runnable的数量>任务队列的长度+最大线程数就会执行饱和策略;

创建线程池的几种方式:

缓存线程池:Executors.newCacheThreadPool();

new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>())

分析: 核心线程数为0,只要有任务来就会创建非核心线程执行任务,在60s的空闲超时时间以内还有任务来就还是用这个非核心线程去执行任务, 如果超过了就会回收这个非核心线程,长时间不用这个线程池的话这个线程中的线程数是0;

单一线程:Executors.newSingleThreadExecutor();

new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())

分析: 核心线程数1,最大线程数1 第一个Runnable来的时候创建一个核心线程,执行,第二个Runnable来的时候发现runnable的数量大于最大线程数1了, 就把会任务放在任务队列中,等核心线程处理完在来任务队列中去任务执行,核心线程1不会被回收,也就是说线程中永远会有一个线程在等着任务.只要使用过一次;

指定线程数大小的线程池:Executors.newFixedThreadPool(nThreads);

new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()

分析: 核心线程数和最大线程数相等,以为着不会存在非核心线程.当任务数量大于核心线程数的时候会把任务放在任务队列中,用空闲线程就会去任务队列中去任务执行; 意味着处理任务的线程最多同时存在的数量是核心线程数;

最新回复(0)