常见的线程池:
newSingleThreadExecutor |
ExecutorService threadPool = Executors.newSingleThreadExecutor(); // 创建只含有单个线程的线程池,如果当前线程在执行任务时突然中断,则会创建一个新的线程去替代它从而继续执行任务。 |
单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务 |
newFixedThreadExecutor(n) |
ExecutorService threadPool = Executors.newFixedThreadPool(3); // 创建可以容纳3个线程的线程池 |
创建一个固定大小的线程池。每次提交一个任务就会创建一个线程,直到创建的线程数量达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变。如果在所有线程都处于活动状态时,这时再有其他任务提交,他们将等待队列中直到有空闲的线程可用。如果任何线程由于执行过程中的故障而终止,将会有一个新线程将取代这个线程执行后续任务。 |
newCacheThreadExecutor(推荐使用) |
ExecutorService threadPool = Executors.newCachedThreadPool(); // 线程池的大小会根据执行的任务数量动态分配 |
CachedThreadPool会创建一个缓存区,将初始化的线程缓存起来,如果线程有可用的,就使用之前创建好的线程,如果没有可用的,就会新创建线程。另外,终止并且从缓存中移除已有60秒未被使用的线程。 |
newScheduleThreadExecutor |
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3); // 效果类似于Timer定时器 |
创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。 |
(1)无论创建哪种线程池,必须要调用 ThreadPoolExecutor类。线程池类是 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler)
- corePoolSize: 线程池维护核心线程的最少数量
- maximumPoolSize:线程池维护线程的最大数量
- keepAliveTime: 线程池维护线程所允许的空闲时间
- unit: 线程池维护线程所允许的空闲时间的单位
- workQueue: 线程池所使用的缓冲队列
- handler: 线程池对拒绝任务的处理策略
(2)一个任务通过 execute(Runnable r ) 方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。
(3)当一个任务通过execute(Runnable)方法 欲添加到线程池时:
- 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
- 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
- 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
- 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
也就是说:处理任务的优先级为:
- 核心线程池corePoolSize、任务队列workQueue、最大线程maximumPoolSize,若三者都满了,使用handler处理被拒绝的任务。
- 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
(4)unit 可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
(5)workQueue 常用的可以是:java.util.concurrent.ArrayBlockingQueue
(6)handler有四个选择:
- ThreadPoolExecutor.AbortPolicy() :抛出java.util.concurrent.RejectedExecutionException异常
- ThreadPoolExecutor.CallerRunsPolicy() :重试添加当前的任务,他会自动重复调用execute()方法
- ThreadPoolExecutor.DiscardOldestPolicy() :抛弃旧的任务
- ThreadPoolExecutor.DiscardPolicy() :抛弃当前的任务