线程池
一,优点:
- 重用线程池中的线程,避免因为线程的创建和销毁带来的开销。
- 能够有效控制线程池的最大并发数,避免线程之间因抢占系统资源而造成阻塞。
- 能够对线程进行简单的管理,比如提供定时执行和间隔执行的功能。
二,线程池概念源于Executor,实际的实现是Th’readPoolExecutor,它提供一些配置参数对线程池进行配置。
new ThreadPoolExecutor(int corePoolSize,
int maxPoolSize,
long timeOut,
TimeUnit unit,
BlockingDeque<Runnable> workQueue,
ThreadFactory threadFactory)
- corePoolSize 核心线程数,默认情况下一直存活,当设置ThreadPoolExecutor的allowCoreThreadTimeOut为true,
则核 心线程闲置超市也会被回收。超时时长为timeOut。
int cpuSize = Runtime.getRuntime().availableProcessors();
一般 核心数 = CUP数,但Intel的超线程技术使得 核心数 = 2 * UPU数;
- maxPoolSize 线程池所能容纳的最大线程数,超过此指定容量后,后续线程将被阻塞。
- timeOut 非核心线程超时时长,当闲置并超过指定时常timeOut将会被回收。
- unit 超时时长单位,MILLISECONDS,SECONDS,MINUTES。
- workQueue 任务队列,通过线程池的execute(Runnable)存储线程到线程池。
- threadFactory 为线程池提供创建新线程的方法,new Thread(Runnable)。
三,ThreadPoolExecutor执行任务时遵循的规则:
- 如果核心线程有空闲,优先启用核心线程。
- 如果核心线程已经全部启动,则后续任务会加入到任务队列排队,等待有核心线程空闲下来后再执行。
- 如果无法插入任务队列,切为达到最大线程池容量,会立即启用一个新线程来执行此任务。
- 如果线程池已达最大容量,则丢弃此任务。
四,因ThreadPoolExecutor的配置不同产生了4类线程池:
- FixedThreadPool 只有固定数量的核心线程,因此会一直存活,无超时限制,不会被回收,除非线程池关闭,且任务队列LinkedBlockingDeque没有大小限制。如果所有核心线程都处于工作状态,后续任务会进入等待状态。
优点:可以快速响应外界请求。优点是可以快速响应外界请求。
public static ExecutorService newFixedThreadPool(int coreSize){
return new ThreadPoolExecutor(coreSize,
coreSize,
0L,
TimeUnit.NANOSECONDS,
new LinkedBlockingDeque<Runnable>());
}
- CacheThreadPool 只有非核心线程,容量为Integer.MAX_VALUE 可以任务是无限大。线程闲置超时timeOut会被回收。 当有新任务时,若有空闲线程则会重用空闲线程来执行此任务,否则启动新线程执行此任务。收。当有新任务时,若有空闲线程则会重用空闲线程来执行此任务,否则启动新线程执行此任务。SynchronousQueue无法存储任务,使得任务到达会立即执行。
优点:适合执行大量耗时较少任务,由于超时机制,当线程池闲置时几乎不占用内存。
public static ExecutorService newCacheThreadPool(){
return new ThreadPoolExecutor(0,
Integer.MAX_VALUE,
60L,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- ScheduledThreadPool 核心线程数固定,非核心线程数不限,切非核心线程超时回收。
优点:主要用于执行定时任务 或 固定周期的重复执行任务。
public static ScheduledExecutorService newScheduledThreadPool(int coreSize) {
return new ScheduledThreadPoolExecutor(coreSize);
}
public ScheduledThreadPoolExecutor(int coreSize){
super(coreSize,Integer.MAX_VALUE,0,TimeUnit.NANOSECONDS,new DelayQueue<>());
}
- SingleThreadExecutor 只有一个核心线程,所有任务都在此现成中按顺序排队执行。
无超时限制,队列无上限限制。
public static ExecutorService newSingleThreadExecutor(){
return new ThreadPoolExecutor(1,
1,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>());
}
四,用法
private void demo() {
Runnable mRunnable = new Runnable() {
@Override
public void run() {
SystemClock.sleep(2000);
}
};
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
fixedThreadPool.execute(mRunnable);
ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
cacheThreadPool.execute(mRunnable);
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
singleThreadPool.execute(mRunnable);
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
scheduledThreadPool.schedule(mRunnable,2000,TimeUnit.MILLISECONDS);
scheduledThreadPool.scheduleAtFixedRate(mRunnable,0,60,TimeUnit.SECONDS);
}