线程池专题
1.什么是线程池:java.util.concurrent.Executors提供了一个java.util.concurrent.Executor接口的实现用于创建线程池。
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假如一个服务器完成一项任务所需时间为:T1创建线程时间,T2在线程中执行任务的时间、T3销毁线程时间。
如果:T1+T3远大于T2,则可以采用线程池,以提高服务器性能。
一个线程池包括一下四个基本组成部分:
1.线程池管理器(ThreadPool):用于创建并管理线程池,包括 ‘创建线程池’、‘销毁线程池’、‘添加新任务’;
2.工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3.任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4.任务队列(taskQueue):用于存储没有处理的任务。提供一种缓冲机制。
线程池技术正式关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1、T3分别安排在服务器程序的启动和结束的时间段或者一些空袭那的时间段,这样在服务器程序处理客户请求时,不会有T1、T3的开销了。
线程池不仅调整T1、T3产生的时间段、而且它还显著减少了创建线程的数目,看一下例子:
假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中的线程的数目,而如果服务器不利用线程池来处理这些请求为50000.一般线程池大小是远小于50000.所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。
2.线程池的作用:
线程池的作用就是限制系统中执行线程的数量.
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
3.为什么要用线程池?
1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。
比较找你更要的几个类:
ExecutorService 真正的线程池接口
ScheduledExecutorService 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题
ThreadPoolExecutor ExecutorService的默认实现
ScheduledThreadPoolExecutor 继承ThreadPoolExecutor和ScheduledExecutorService接口实现,周期性任务调度的类实现。
要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是最优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。
2.常见线程池
1.newSingleThreadExecutor
单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务。
2.newFixedThreadExecutor(n)
固定数量的线程池,每提交一个任务就是一个线程,直到达到线程池的最大数量,然后后面进入等待队列直到前面的任务完成才继续执行。
3.newCacheThreadExecutor(推荐使用)
可缓存线程池,当线程池大小超过了处理任务所需的线程,那么就会回收部分空闲(一般是60秒无执行)的线程,当有任务来时,又智能的添加新线程来执行。
4.newScheduleThreadExecutor
大小无限制的线程池,支持定时和周期性的执行线程
代码如下:
略