为什么要使用线程池?
线程的创建和销毁都是需要消耗大量系统资源的,如果能管理好线程的生命周期,减少线程频繁的创建、销毁次数,对多任务共用一个线程,不仅能节省系统资源,还能减少了线程创建造成的延迟,系统响应速度也增加了。
适用场景?
Web服务器处理大量的运行时间短的线程,这样能大大减少线程创建和销毁的开销。
线程池:
ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
corePoolSize:池中保留的线程数(即使这些线程休眠,除非设置allowCoreThreadTimeOut)
maximumPoolSize:池中允许的最大线程数
keepAliveTime:当池中的线程数多于core的线程数,除core线程之外的休眠线程能够存活的时间
unit:keepAliveTime的时间单位
workQueue:还未执行的任务队列,这个队列仅仅持有Runnable任务,并将任务提交到execute方法执行
下列四种是平常用到的四种线程池:
Executors.newFixedThreadPool(int nThreads)
new ThreadPoolExecutor(nThreads,nThreads,0L,
TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
创建一个可重复使用线程的,操作共享并共享一个无边界队列的线程池,数量为nThreads。在任意时刻,最多存在nThreads个线程处理task。当所有线程都处于active状态时,如果有额外的tasks,此时队列的tasks需等待其中某个线程可用。任何线程由于在执行期间失败导致终止的,一个新的线程将会替代它并执行随后的tasks。如果不明确的使用ExecutorService.shutdown,线程池中的线程会一直存在
Executors.newCachedThreadPool()
new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L
TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
这个池子会先使用之前已经构建的可用线程,如果没有则会新建一个。当执行大量short-lived异步任务时,使用该线程能提高效率。如果池子中有线程超过60秒没有被使用则会移除该线程。
Executors.newSingleThreadExecutor()
new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
创建只有一个线程的线程池
Executors.newScheduledThreadPool(int corePoolSize)
new ThreadPoolExecutor(corePoolSize,Integer.MAX_VALUE,0
NANOSECONDS,new DelayedWorkQueue());
创建一个可以定期执行的或者在给定某个时间之后执行的线程池