线程池初解1
前言
- 为什么使用线程池
- 降低资源消耗:线程的创建和销毁是比较消耗资源的操作,频繁地创建和销毁线程会增加系统的开销。使用线程池可以避免频繁地创建和销毁线程,重复利用线程对象,降低资源消耗。
- 提高响应速度:线程池中的线程是预先创建好的,当有任务到来时,可以立即执行,避免了线程创建的开销,提高了任务的响应速度。
- 控制并发数量:线程池可以限制同时执行的线程数量,避免系统资源被耗尽,防止因并发数量过大导致系统崩溃。
- 提高程序的可维护性:使用线程池可以将任务的执行和线程的管理分离,使得程序结构更清晰、更易于维护。
- 提供任务队列:线程池通常会提供一个任务队列,用于存放等待执行的任务,避免任务的丢失,提高任务的处理能力。
- 提供线程池管理功能:线程池可以提供线程的生命周期管理、线程的状态监控、异常处理等功能,方便对线程的管理和监控。
- java中创建一个线程的方法
- 实现Runnable接口(无返回值)
- 实现Callable接口(有返回值)
- 继承Thread类(和1一样,因为Thread类也实现了Runnable接口)
源码解析
Executor接口
执行已提交 Runnable 任务的对象。此接口提供了一种将任务提交与每个任务的运行机制解耦的方法,包括线程使用、调度等细节。通常使用 An Executor 而不是显式创建线程。Executor接口的实现类通常是线程池,通过将任务提交给线程池来执行。
public interface Executor {
/**
* 该任务执行没有提供返回值
*/
void execute(Runnable command);
}
ExecutorService接口
ExecutorService继承了Executor,是一个更完整的接口新增了有返回值的submit方法以及可以关闭线程池的shutdown和shutdownNow方法,还有批量处理多个任务的的方法
public interface ExecutorService extends Executor {
/**
* 关闭线程池,不会接收新的任务,但是任务队列中的任务还会继续处理
*/
void shutdown();
/**
* 立刻关闭线程池,不会接受新的任务,也不会处理任务队列中的任务,尝试停止所有正在执行的任务,
* 返回等待执行的任务列表
*/
List<Runnable> shutdownNow();
/**
* 线程池是否被关闭
*/
boolean isShutdown();
/**
* 如果所有任务在线程池关闭后都已完成,则返回true。请注意,isTerminated除非先调用 or shutdown shutdownNow 否则永远不会true。
*/
boolean isTerminated();
/**
* 阻塞,直到所有任务在关闭请求后完成执行,或发生超时,或当前线程中断,以先发生者为准
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 提交值返回任务以供执行,并返回表示任务的待处理结果的 Future。Future get 的方法将在成功完成后返回任务的结果。
* 提交一个任务,返回一个Future,通过Future.get()获取任务的返回结果
*/
<T> Future<T> submit(Callable<T> task);
/**
* 提交要执行的 Runnable 任务,并返回表示该任务的 Future。Future get 的方法将在成功完成后返回给定的结果。
* Future.get()返回的结果为result
*/
<T> Future<T> submit(Runnable task, T result);
/**
* 提交要执行的 Runnable 任务,并返回表示该任务的 Future。Future get 的方法将在成功完成后返回给定的结果。
* Future.get()返回的结果为null
*/
Future<?> submit(Runnable task);
/**
* 执行给定的任务,并在全部完成后返回一个 Futures 列表,其中包含它们的状态和结果。 Future.isDone 用于 true 返回列表的每个元素。请注意,已完成的 * 任务可能已正常终止,也可能因引发异常而终止。如果在此操作过程中修改了给定的集合,则此方法的结果未定义。
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
/**
* 执行给定的任务,当所有任务全部完成或超时到期时(以先发生者为准),返回一个 Futures 列表,其中包含其状态和结果。 Future.isDone 用于 true 返回列 * 表的每个元素。返回后,未完成的任务将被取消。请注意,已完成的任务可能已正常终止,也可能因引发异常而终止。如果在此操作过程中修改了给定的集合,则此方 * 法的结果未定义。
*/
<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;
}
AbstractExecutorService接口
AbstractExecutorService
是ExecutorService
接口的一个抽象实现类,它提供了ExecutorService
接口的部分实现。ExecutorService
是Java中用于管理线程池的接口,可以用来执行异步任务。
AbstractExecutorService
提供了一些方法的默认实现,简化了自定义线程池的实现。它允许子类只实现核心的执行逻辑,而其他方法如submit
、invokeAll
、invokeAny
等则已经有了默认实现。(模板方法)
提供执行方法的ExecutorService默认实现。submit此类使用 RunnableFuture 返回的 实现 newTaskFor和 invokeAny invokeAll 方法,该方法默认为FutureTask此包中提供的类。例如,的实现submit(Runnable)创建一个执行并返回的关联RunnableFuture。子类可以重写newTaskFor方法以返回 RunnableFuture 以外的实现FutureTask.
public abstract class AbstractExecutorService implements ExecutorService {
/**
* 返回给定可运行对象和默认值的 a RunnableFuture 。实例为FutureTask
* 子类可重写此方法返回其他的RunnableFuture实例
*/
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
/**
* 返回给定可调用任务的 a RunnableFuture 。实例为FutureTask
* 子类可重写此方法返回其他的RunnableFuture实例
*/
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
/**
* submit方法接收Runnable返回Future,返回的Future是RunnableFuture接口,实例为FutureTask
*/
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
/**
* submit方法接收Runnable,result返回Future,返回的Future是RunnableFuture接口,实例为FutureTask
*/
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
/**
* submit方法接收Callable返回Future,返回的Future是RunnableFuture接口,实例为FutureTask
*/
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
/**
* the main mechanics of invokeAny.
*/
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
boolean timed, long nanos)
throws InterruptedException, ExecutionException, TimeoutException {
if (tasks == null)
throw new NullPointerException();
int ntasks = tasks.size();
if (ntasks == 0)
throw new IllegalArgumentException();
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
//完成的调用执行服务 使用QueueingFuture作为任务单元 重写了FutureTask的Done方法 将已经完成的任务放到一个阻塞队列中
ExecutorCompletionService<T> ecs =
new ExecutorCompletionService<T>(this);
// For efficiency, especially in executors with limited
// parallelism, check to see if previously submitted tasks are
// done before submitting more of them. This interleaving
// plus the exception mechanics account for messiness of main
// loop.
try {
// Record exceptions so that if we fail to obtain any
// result, we can throw the last exception we got.
ExecutionException ee = null;
//超时时间点
final long deadline = timed ? System.nanoTime() + nanos : 0L;
Iterator<? extends Callable<T>> it = tasks.iterator();
// Start one task for sure; the rest incrementally
futures.add(ecs.submit(it.next()));
//剩余任务数
--ntasks;
//正在执行的任务数
int active = 1;
for (;;) { //自旋
//在已完成的任务阻塞队列中取出一个
Future<T> f = ecs.poll();
//还没有完成的任务
if (f == null) {
if (ntasks > 0) {
--ntasks;
futures.add(ecs.submit(it.next()));
++active;
}
//所有任务都出现了异常
else if (active == 0)
break;
//当任务已经全部去执行时 超时等待获取结果
else if (timed) {
f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null)
throw new TimeoutException();
nanos = deadline - System.nanoTime();
}
else
//当任务已经全部去执行时 阻塞 获取结果 直到有任务完成
f = ecs.take();
}
//已经有完成的任务了
if (f != null) {
--active;
try {
//返回任务结果
return f.get();
} catch (ExecutionException eex) {
//执行异常 出现异常后不会返回 找到执行成功的任务
ee = eex;
} catch (RuntimeException rex) {
//执行异常 出现异常后不会返回 找到执行成功的任务
ee = new ExecutionException(rex);
}
}
}
if (ee == null)
ee = new ExecutionException();
throw ee;
} finally {
for (int i = 0, size = futures.size(); i < size; i++)
//取消任务
futures.get(i).cancel(true);
}
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
try {
return doInvokeAny(tasks, false, 0);
} catch (TimeoutException cannotHappen) {
assert false;
return null;
}
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return doInvokeAny(tasks, true, unit.toNanos(timeout));
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
//一个任务数组
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
//遍历任务数组执行
for (Callable<T> t : tasks) {
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
execute(f);
}
//遍历futures列表
for (int i = 0, size = futures.size(); i < size; i++) {
Future<T> f = futures.get(i);
//对于没有完成的任务执行 get 阻塞当前线程
if (!f.isDone()) {
try {
f.get();
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
}
}
}
//所有的任务全部完成
done = true;
return futures;
} finally {
//没有完成 则操作future进行取消
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
//已经完成的任务取消不受影响
futures.get(i).cancel(true);
}
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks)
futures.add(newTaskFor(t));
//截至时间点
final long deadline = System.nanoTime() + nanos;
final int size = futures.size();
// Interleave time checks and calls to execute in case
// executor doesn't have any/much parallelism.
for (int i = 0; i < size; i++) {
execute((Runnable)futures.get(i));
//剩余时间
nanos = deadline - System.nanoTime();
if (nanos <= 0L)
//超时直接返回
return futures;
}
for (int i = 0; i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
if (nanos <= 0L)
return futures;
try {
//在给定的时间内获取结果
f.get(nanos, TimeUnit.NANOSECONDS);
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
} catch (TimeoutException toe) {
//执行超时直接返回
return futures;
}
//剩余时间
nanos = deadline - System.nanoTime();
}
}
done = true;
return futures;
} finally {
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
//已经完成的任务取消不受影响
futures.get(i).cancel(true);
}
}
}