线程池
项目文件:HelloJava-ThreadPoolExecutorDemo
-
线程池优点:
- 重用线程,避免创建和销毁线程的性能开销;
- 有效控制线程池最大并发数,避免大量线程之间因互相抢占系统资源而导致的阻塞现象;
- 能对线程进行简单管理,并提供定时执行已经间隔循环执行等功能;
-
继承关系:源于Executor;真正实现是ThreadPoolExecotor;
public interface Executor { void execute(Runnable command); } public interface ExecutorService extends Executor {...} public abstract class AbstractExecutorService implements ExecutorService {...} public class ThreadPoolExecutor extends AbstractExecutorService {...}
-
ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue ThreadFactory threadFactory RejectedExecutionHandler handler){ ... private volatile boolean allowCoreThreadTimeOut; ... }
corePoolSize:核心线程数,核心线程会在线程池中一直存活。如果allowCoreThreadTimeOut为true,闲置的核心线程等待时长超过keepAliveTIme所指定的时长,核心线程会被终止;
maximumPoolSize:线程池所能容纳的最大线程数;
keepAliveTime:非核心线程闲置的超时时长,超过时长,非核心线程被回收;如果allowCoreThreadTimeOut为true,同样作用于核心线程;
unit: keepAliveTime参数的时间单位,枚举值,常用TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS、TimeUnit.MINUTES;
workQueue:任务队列,通过线程execute方法提交的Runnable对象会存储在这个参数中;
-
threadFactory:线程工厂,为线程池提供创建新线程的功能。
public interface ThreadFactory { Thread newThread(Runnable r); }
RejectedExecutionHandler handler:当线程池无法执行新任务,如任务队列已满或者无法成功执行任务,会调用handler.rejectedExecution,默认抛出异常。
-
ThreadPoolExecutor执行流程:
- 先开核心线程;
- 填充任务队列;
- 任务队列满了但未达到maximumPoolSize,再开非核心线程;
- 线程池数量达到线程池规定的最大值maximumPoolSize,handler抛出异常;
-
线程池分类:
-
FixedThreadPool:线程数量固定,只有核心线程且不会被回收;任务队列没有大小限制;
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
-
CachedThreadPool:只有非核心线程,线程数量不定;超时60s回收;SynchronousQueue可以理解为无法存储元素的队列;适合执行大量的、耗时少的任务,当线程池闲置时,线程都会被超时回收,几乎不占用系统资源;
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
-
ScheduledThreadPool:核心线程固定,非核心线程没有限制,非核心线程闲置立即回收(keepAliveTime为0);主要执行定时任务和周期任务;schedule:计划(表),进度表,调度。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
-
SingleThreadPool:只有一个核心线程;所有任务统一到一个线程,不需要处理线程同步问题。
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
-
-
通过Executors来创建线程池;(非Executor)
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); fixedThreadPool.execute(runnable); ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(runnable); ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4); scheduledThreadPool.execute(runnable); ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); singleThreadExecutor.execute(runnable);