Executor 英文意思是执行者,可以看出它的作用是提交和执行任务接口,也可以理解为是线程池。
Executor 有一个子接口 ExecutorService,ExecutorService 可以管理和终止任务的方法,可以追踪异步任务的进度的 Executor。
Executors 是线程池的工厂类,提供静态工具方法。使用 Executors 可以方便地创建各种类型的线程池。但是由于 Executors 创建的线程池内部很多地方用到了无界任务队列,在高并发场景下,无界任务队列会接收过多的任务对象,导致 JVM 抛出OutOfMemoryError,整个 JVM 服务崩溃,影响严重。所以很多公司已经不建议使用 Executors 去创建线程。
简单介绍下 Executors 的使用:
newFixedThreadPool:创建定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程
newCachedThreadPool:创建可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制
newScheduledThreadPool:创建定长线程池,可执行周期性的任务
newSingleThreadExecutor:创建单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行
newSingleThreadScheduledExecutor:创建单线程可执行周期性任务的线程池
newWorkStealingPool:任务可窃取线程池,不保证执行顺序,当有空闲线程时会从其他任务队列窃取任务执行,适合任务耗时差异较大
JDK 提供的线程池相关的工具类中,最核心的是 ThreadPoolExecutor。它最复杂的构造函数有 7 个参数:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
hreadFactory threadFactory,
RejectedExecutionHandler handler)
参数说明:
corePoolSize:线程池保有的最小线程数
maximumPoolSize:线程池创建的最大线程数
keepAliveTime:一个线程空闲了 keepAliveTime * unit 这么长时间,且线程池的线程数大于 corePoolSize ,那么这个空闲的线程就要被回收了
unit:keepAliveTime 的时间单位
workQueue:任务队列
threadFactory:线程工厂对象,可以自定义如何创建线程,如给线程指定 name
handler:自定义任务的拒绝策略。线程池中所有线程都在忙碌,且任务队列已满,线程池就会拒绝接收再提交的任务。handler 就是拒绝策略,包括 4 种(即 RejectedExecutionHandler 接口的 4个实现类)
AbortPolicy:默认的拒绝策略,throws RejectedExecutionException
CallerRunsPolicy:提交任务的线程自己去执行该任务
DiscardPolicy:直接丢弃任务,不抛出任何异常
DiscardOldestPolicy:丢弃最老的任务,加入新的任务
使用示例:
package constxiong.interview;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 测试 ThreadPoolExecutor 创建线程池
* @author ConstXiong
*/
public class TestThreadPoolExecutor {
public static void main(String[] args) {
testSubmitTask();
}
/**
* 测试使用 ThreadPoolExecutor 创建线程池,并向线程池提交任务
*/
private static void testSubmitTask() {
int corePoolSize = 1;//最小线程数
int maximumPoolSize = 2;//最大线程数
long keepAliveTime = 1000L;//1000个单位时间
Executor exector = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.MILLISECONDS,
new SynchronousQueue<Runnable>(),//可以修改队列:有界队列、无界队列、有优先级的队列
Executors.defaultThreadFactory(),//线程工程对象,可以定义如何创建线程
new ThreadPoolExecutor.AbortPolicy()); //任务队列已满,线程池决绝策略
for (int i = 0; i < 5; i++) {
exector.execute(() -> {
System.out.println(Thread.currentThread().getName());
});
}
}
}
ConstXiong 备案号:苏ICP备16009629号-3