对Executor框架简介
Executor框架实现了线程的提交和执行的解耦开发,易于扩展,采用线程中的生产者和消费者模式进行解耦开发,比如线程的提交相当于生产者,线程的执行相当于消费者.
1.Executor框架继承实现介绍:
Executor的UML图:
Executor:一个接口,只有一个接收runnable的构造方法:
ExecutorService:比Executor使用更广泛的接口,继承了Executor接口:
AbstractExecutorService:实现了ExecutorService的接口:
ScheduledExecutorService:继承了ExecutorService,作用是可定时调度任务的接口 :
ThreadPoolExecutor:继承了AbstractExecutorService,对线程进行管理
:
ScheduledThreadPoolExecutor:实现了ScheduledExecutorService,继承了ThreadPoolExecutor,可定时调度任务的线程池
2.ThreadPoolExecutor构造函数的各个参数说明:
源码:英文版说明:
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default rejected execution handler.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @throws IllegalArgumentException if one of the following holds:
* {@code corePoolSize < 0}
* {@code keepAliveTime < 0}
* {@code maximumPoolSize <= 0}
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
中文翻译:
corePoolSize:保留在池中的线程数,即使它们是空闲的,也就是说,你设置了4,但是你只放了3个线程,那它还是会创建一个线程,即使它是空的.如果你没有设置最大线程maximumPoolSize,那它就是最大线程数量;
maximumPoolSize:最大线程数,maximumPoolSize>=corePoolSize;
keepAliveTime:当执行的线程数量大于corePoolSize的数量时,它空闲等待的时间,如果超过的话,就终止;
unit:keepAliveTime参数的时间单位;
workQueue:
保存任务的阻塞队列,与线程池的大小有关:
当运行的线程数少于corePoolSize时,在有新任务时直接创建新线程来执行任务而无需再进队列
当运行的线程数等于或多于corePoolSize,在有新任务添加时则选加入队列,不直接创建线程
当队列满时,在有新任务时就创建新线程;
threadFactory :执行器(executor)使用的工厂;
3.Executors工具类的使用:
newFixedThreadPool:创建一个固定数量的线程池,如果出现额外的线程,要等池中的线程执行完之后才能进入,而这个额外的线程将放入到队列中等待.
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
newScheduledThreadPool:创建一个可延迟执行或定期执行的线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
举例子:
(newFixedThreadPool这个构造方法就不讲了)
newScheduledThreadPool:
public static void main(String[] args) {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
Runnable task1=new Runnable() {
public void run() {
System.out.println("我是任务1,检测了!");
}
};
Runnable task2=new Runnable() {
public void run() {
System.out.println("我是任务2,检测了!");
}
};
pool.scheduleWithFixedDelay(task1, 1, 3, TimeUnit.SECONDS);
pool.scheduleWithFixedDelay(task2, 2, 3, TimeUnit.SECONDS);
}
结果:
4.Executor的生命周期
包括:运行/关闭和终止三个状态
public static void main(String[] args) {
ExecutorService pool = Executors.newScheduledThreadPool(5);
Thread task1=new Thread(()-> {
System.out.println("i am task1");
});
Thread task2=new Thread(()-> {
System.out.println("i am task2");
});
// pool.execute(task1);
// pool.execute(task2);
pool.submit(task1);
pool.submit(task2);
}
通过Executor来设计应用程序可以简化开发过程,提高开发效率,并有助于实现并发,在开发中如果需要创建线程可优先考虑使用Executor