使用线程池有以下几个目的
A.线程是稀缺资源,不能频繁的创建。
B.解耦作用;线程的创建与执行完全分开,方便维护。
C.应当将其放入一个池子中,可以给其他任务进行复用。
线程池原理
核心的思想就是把宝贵的资源放到一个池子中;每次使用都从里面获取,用完之后又放回池子供其他人使用。
ThreadPoolExecutor通常使用工厂类Executors来创建。Executors可以创建3种类型的ThreadPoolExecutor:
Executors.newCachedThreadPool():可变大小的线程池(无限线程池)。Executors来创建线程池默认的最大容量是Integer.Max,也就是Integer的最大值作为线程池的最大容量
Executors.newFixedThreadPool(nThreads):创建固定大小的线程池。
Executors.newSingleThreadExecutor():创建单个线程的线程池。(需要有序的时候使用)
ScheduledThreadPoolExecutor通常使用工厂类Executors来创建。Executors可以创建2种类型的ScheduledThreadPoolExecutor:安排延迟或者定时执行任务
SingleScheduledThreadPoo和();单例定时线程池
ScheduledThreadPool();定时线程池
接口:
ExecutorsService
创建线程:
new Thread()//代表真正意义的线程 有star …完整的生命周期
implement Runnable ------>之后还是要借助new Thread()创建线程,只是对run方法重写
创建线程池:
ExecutorsService pool = Executors.newFixedThreadPool(3);//创建一个数量为三的固定线程池
pool.execute(task);//task为任务线程
创建线程池参数:
corePoolSize:核心线程数量
maximumPoolSize:最大线程数量;
workQueue:等待队列,当任务提交时,如果线程池中的线程数量大于等于corePoolSize的时候,把该任务封装成一个Worker对象放入等待队列;
keepAliveTime:线程池维护线程所允许的空闲时间。当线程池中的线程数量大于corePoolSize的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了keepAliveTime;
TimeUnit :时间级别
threadFactory:它是ThreadFactory类型的变量,用来创建新线程。
handler:它是RejectedExecutionHandler类型的变量,表示线程池的饱和策略(拒绝策略)。如果阻塞队列满了并且没有空闲的线程,这时如果继续提交任务,就需要采取一种策略处理该任务。
ThreadFactory:定义线程池中创建的线程,如线程名称,优先级等,可以几次ThreadFactory重新newThread(Runnable r)方法。
停止线程池方法
TIDYING
状态说明:当所有的任务已终止,任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。
最后
有一点是肯定的,线程池肯定是不是越大越好。
通常我们是需要根据这批任务执行的性质来确定的。
IO 密集型任务:由于线程并不是一直在运行,所以可以尽可能的多配置线程,比如 CPU 个数 * 2
CPU 密集型任务(大量复杂的运算)应当分配较少的线程,比如 CPU 个数相当的大小。