java线程池源码阅读
说明
简单理解和使用可以参考:https://www.cnblogs.com/LQBlog/p/8735356.html
类图
接口
Executor接口
public interface Executor { /** * 代表提交了一个任务 * @param command */ void execute(Runnable command); }
简单的实现
1.希望同步执行任务的实现
public class SimpleExecutor implements Executor { @Override public void execute(Runnable command) { command.run();; } }
2.基于线程运行任务的实现
public class ThreadExecutor implements Executor{ @Override public void execute(Runnable command) { new Thread(command).start(); } }
ExecutorService接口
Executor太简单了,只能提交任务,往往我们需要关注线程池状态,执行了多少个任务,完成多少个任务,线程池塘线程数量等,Excutor不能满足,所以需要看ExecutorService接口基于Executor的扩展public interface
interface ExecutorService extends Executor { /** * 关闭线程池,已提交的任务继续执行,不接受继续提交新任务 */ void shutdown(); /** * 关闭线程池,尝试停止正在执行的所有任务,不接受继续提交新任务 * 它和前面的方法相比,加了一个单词“now”,区别在于它会去停止当前正在进行的任务 * * @return */ List<Runnable> shutdownNow(); /** * 判断线程池是否已关闭 * @return */ boolean isShutdown(); /** * 如果调用了 shutdown() 或 shutdownNow() 方法后,所有任务结束了,那么返回true * 这个方法必须在调用shutdown或shutdownNow方法之后调用才会返回true */ boolean isTerminated(); /** * 等待所有任务完成,并设置超时时间 * 我们这么理解,实际应用中是,先调用 shutdown 或 shutdownNow, * 然后再调这个方法等待所有的线程真正地完成,返回值意味着有没有超时 InterruptedException if interrupted while waiting */ boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; /** * 提交一个 Callable 任务 内部会包装成Future */ <T> Future<T> submit(Callable<T> task); /** * 提交一个 Runnable 任务,第二个参数将会放到 Future 中,作为返回值, * 因为 Runnable 的 run 方法本身并不返回任何东西 内部会用Future包装 */ <T> Future<T> submit(Runnable task, T result); /** * 提交一个 Runnable 任务 */ Future<?> submit(Runnable task); /** * 执行所有任务,返回 Future 类型的一个 list*/ <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; /** * 同上一个方法,只有其中的一个任务结束了,就可以返回,返回执行完的那个任务的结果, * 不过这个带超时,超过指定的时间,抛出 TimeoutException 异常*/ <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
AbstractExecutorService
是一个抽象类,对ExecutorService的相关方法进行了实现
public abstract class AbstractExecutorService implements ExecutorService { /** * 包装成futureTask */ protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value); } /** * 包装成futureTask */ protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); } /** * 包装成futureTask */ public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); //具体执行任务交给子类执行 execute(ftask); return ftask; } /** * 包装成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; } /** * 包装成futureTask */ public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; } /** * */ 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(); //初始化task list容器 ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks); //交给ExecutorCompletionService 只负责调度,最终内部执行任务还是调用的 this的execute ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this); try { ExecutionException ee = null; //是不是带有超时时间的 final long deadline = timed ? System.nanoTime() + nanos : 0L; Iterator<? extends Callable<T>> it = tasks.iterator(); //预执行第一个任务 ecs.submit内部也是调用 当前对象的execute futures.add(ecs.submit(it.next())); //task数量-1 --ntasks; //提交的任务数 int active = 1; //遍历 for (;;) { //获取执行结果内部是调用ecs completionQueue如果返回会将结果放入此queue Future<T> f = ecs.poll(); //如果上一个任务没有执行完毕,针对第一次则是与预执行那个任务,则继续提交任务 if (f == null) { //表示还有任务 继续提交任务 if (ntasks > 0) { --ntasks; futures.add(ecs.submit(it.next())); ++active; } else if (active == 0)//当为0 表示下面 f!=null 每次都异常 任务没有了 结束 break; else if (timed) {//当任务提交完毕,则最后调用poll尝试等待指定时机 f = ecs.poll(nanos, TimeUnit.NANOSECONDS); if (f == null)//等待指定四航局 还未获取到结果则抛出超时异常 throw new TimeoutException(); nanos = deadline - System.nanoTime(); } else//非超时执行task f = ecs.take(); } //表示获取到结果 if (f != null) { --active;//-1 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 { //调用doInvokeAny 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 { //调用doInvokeAny 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) { //包装成future RunnableFuture<T> f = newTaskFor(t); //加入futures futures.add(f); //执行任务并调用子类的execute方法 execute(f); } //遍历检查所有任务结果 for (int i = 0, size = futures.size(); i < size; i++) { Future<T> f = futures.get(i); if (!f.isDone()) { try { // 这是一个阻塞方法,直到获取到值,或抛出了异常 // 这里有个小细节,其实 get 方法签名上是会抛出 InterruptedException 的 // 可是这里没有进行处理,而是抛给外层去了。此异常发生于还没执行完的任务被取消了 f.get(); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } } } //表示都检查完毕 done = true; //返回结果 return futures; } finally { //上面执行任务检查并没有cache所有异常,以及execute提交任务拒绝策略也会抛出异常,、针对这种情况取消其他任务 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()) { //超时时间为0 返回所有任务 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); } } }
ExecutorCompletionService实现
public class ExecutorCompletionService<V> implements CompletionService<V> { //真正执行任务的地方 我们的线程池对象 private final Executor executor; //线程池对象 private final AbstractExecutorService aes; private final BlockingQueue<Future<V>> completionQueue; /** * 内部类实现了futureTask * 对RunnableFuture进行了增强 */ private class QueueingFuture extends FutureTask<Void> { QueueingFuture(RunnableFuture<V> task) { super(task, null); this.task = task; } /** * 增强方法 */ protected void done() { //任务执行完毕则将task加入completionQueue completionQueue.add(task); } private final Future<V> task; } private RunnableFuture<V> newTaskFor(Callable<V> task) { if (aes == null) return new FutureTask<V>(task); else //调用的我们线程池的newTaskFor方法包装任务 return aes.newTaskFor(task); } private RunnableFuture<V> newTaskFor(Runnable task, V result) { if (aes == null) return new FutureTask<V>(task, result); else //调用的我们线程池的newTaskFor方法包装任务 return aes.newTaskFor(task, result); } //构造方法 public ExecutorCompletionService(Executor executor) { if (executor == null) throw new NullPointerException(); this.executor = executor; this.aes = (executor instanceof AbstractExecutorService) ? (AbstractExecutorService) executor : null; this.completionQueue = new LinkedBlockingQueue<Future<V>>(); } //构造方法 可以可以自己设置completionQueue public ExecutorCompletionService(Executor executor, BlockingQueue<Future<V>> completionQueue) { if (executor == null || completionQueue == null) throw new NullPointerException(); this.executor = executor; this.aes = (executor instanceof AbstractExecutorService) ? (AbstractExecutorService) executor : null; this.completionQueue = completionQueue; } public Future<V> submit(Callable<V> task) { if (task == null) throw new NullPointerException(); RunnableFuture<V> f = newTaskFor(task); //最终还是委托给真正的线程池 executor.execute(new java.util.concurrent.ExecutorCompletionService.QueueingFuture(f)); return f; } public Future<V> submit(Runnable task, V result) { if (task == null) throw new NullPointerException(); RunnableFuture<V> f = newTaskFor(task, result); //最终还是委托给真正的线程池 executor.execute(new java.util.concurrent.ExecutorCompletionService.QueueingFuture(f)); return f; } public Future<V> take() throws InterruptedException { //返回任务结果 return completionQueue.take(); } public Future<V> poll() { //返回任务结果 return completionQueue.poll(); } public Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException { //返回任务结果 return completionQueue.poll(timeout, unit); } }
标签:
并发编程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!