合理利用线程池的好处
1:降低资源消耗 : 重复利用已创建的线程,降低线程的创建和销毁的消耗
2:提高响应速度:当任务到达时,线程不用创建就能立马执行。
3:提高线程的可管理性:线程池可以对线程进行同意分配,调度和监控。
线程池主要处理流程
当提交一个任务到线程池后:
1:线程池判断核心线程池里的线程是否都在执行任务,不是,则创建一个线程执行任务,是,进入下一个流程。
2:线程池判断工作队列是否已满,没有,则提交任务到工作队列存储,满了,进入下个流程。
3:线程池判断线程池的线程是否都处于工作状态,如果没有则创建一个线程来执行任务,已经满了,交给饱和策略来处理。

线程池的使用
1:创建线程池:可以通过ThreadPoolExecutor来创建一个线程池.
new ThreadPoolExecutor(CorePoolSize,maximumPoolSize,
keepAliveTime,runnableTaskQUeue, handler );
参数说明:
1:corePoolSize:线程池的基本大小,核心线程池的大小,当提交一个任务时,无论核心线程有其他线程空闲,也会创建线程,直到到达核心线程的大小
2:runnableTaskQueue:用于保存等待执行的任务的阻塞队列,可以选择以下几个
1>:ArrayBlockingQueue:基于数组的有界阻塞队列
2>:LinkedBlockQueue:基于链表的阻塞队列,
3>:SynchronousQueue:一个不存储元素的阻塞队列,
4>;PriorityBlockQueue:基于优先级的无限阻塞队列.
3:maximumPoolSize:线程池允许创建的最大线程数,
4:ThreadFactory:设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字
5:RejectedExecutionHandler:饱和策略,当队列和线程池都满了,说明线程池处于饱和状态,就要采取一种策略处理提交的新任务,默认是AbortPolicy,表示无法处理直接抛出异常,java有4中策略
1>:abortPolicy:直接抛出异常
2>:CallerRunsPolicy:只用调用者所在的线程来运行任务
3:DiscardOldestPolicy:丢弃队列中最老的任务,并执行当前任务。
4:DiscardPolicy:不处理直接丢弃掉。
6:keepAliveTime:线程活动保持时间,线程池的工作线程空闲后,保持存活的时间。
7:TImeUnit:线程保活时间的时间单位。
2:向线程池提交任务:
两种方法execute submit
1,execute:用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。
threadsPool.execute(new Runnable(){
@Override
public void run(){
}
});
2:submit()用于提交有返回值的任务,线程池会返回一个future类型的对象,通过future对象可以判断线程是否执行成功。
这个方法后期会详细介绍
3:关闭线程池
shutdown shutdownNow
原理是:通过遍历线程池中的线程,然后逐个调用interrupt方法中断线程,,
区别:根据提交的任务特性来决定,一半都使用shurdown,如果任务不一定要执行完,可以调用shurdownnow
4:合理的配置线程池:
根据不同的任务特性,可以从以下几个角度分析
1:任务的性质:CPU密集型,IO密集型,混合任务
2:任务的优先级:高中低
3:任务执行的时间:长 中 短
4:任务的依赖性:是否依赖其他系统资源,如SQL,
eg:依赖数据库,任务需要等待数据库返回结果,这个时间较长,CPU空闲时间较多,可以设置线程数较大的值,更好的利用CPU.
5:线程池监控,
大量使用线程池就需要对线程池随时掌控,可以通过线程池提供的参数进行监控。
1:taskCount:线程池需要执行的任务数量。
2:complatedTaskCount:线程池完成的任务数量。
3:largestPoolSize:线程池曾经创建过的最大线程数量。
4:getPoolSize:线程池的线程数量。线程池不销毁,里面的线程不会自动销毁,所以这个参数只增不减。
5:getActiveCount:获取活动的线程数。
扩展线程池进行监控:自定义线程重写线程池的beforeExecute afterExecute terminated来监控任务执行前,执行后,和关闭线程池