Executor
Executor 是一个抽象层面的 根接口,下面是它的源代码:
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
可以看到,该接口中就只有一个execute()方法
那 Thread and Executor 的区别在哪,为什么已经有了 Thread 又要弄个 Executor 接口出来,在 Java 中,Thread 和 Executor(及其扩展接口/实现类)是两种不同的任务执行模型,不同于 Thread 类将任务和执行耦合在一起,
Executor将 任务本身和执行任务分离共同点:两者最终都通过
Runnable或Callable定义任务逻辑协作场景:
ThreadPoolExecutor(Executor的实现类)内部实际使用Thread来执行任务
graph LR
Thread(Thread) -->|手动管理| Runnable/Callable
Executor(Executor) -->|统一调度| Runnable/Callable
Executor --> ExecutorService --> ThreadPoolExecutor
ExecutorService
ExecutorService 接口,是继承了 Executor 接口并对其进行了扩展,例如提供了返回 Future 对象,终止,关闭线程池等方法
public interface ExecutorService extends Executor, AutoCloseable {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
@Override
default void close() {
boolean terminated = isTerminated();
if (!terminated) {
shutdown();
boolean interrupted = false;
while (!terminated) {
try {
terminated = awaitTermination(1L, TimeUnit.DAYS);
} catch (InterruptedException e) {
if (!interrupted) {
shutdownNow();
interrupted = true;
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
}
Future 接口
Future 提供了异步执行,无需等待任务执行完成,只要提交需要执行的任务,然后在需要时检查 Future 是否已经有了结果,如果任务已经执行完成,就可以通过 Future.get() 方法获得执行结果,但需要注意的是,Future.get() 方法是一个阻塞的方法,如果调用时任务还没有执行完,会保持等待直到任务执行结束
Executors
Executors 类似于 Collections 、Arrays 等 ,是一个工具类,提供了一系列静态方法来创建不同类型的线程池,但是一般都会采用自定义线程池的方式来实现,因为Executors虽然方便,但是不利于控制线程池的运行规则,可能会导致资源耗尽的风险
// 固定大小线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(10);
// 缓存线程池
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 单线程线程池
ExecutorService singlePool = Executors.newSingleThreadExecutor();
// 定时任务线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(5);