摘要:而中直接将任务交给运行再来看创建一个保存所有的结果运行任务依次取结果这里使用是为了等待运行完成,如果没完成就会阻塞如果发生异常,则取消所有任务续线程池的原理学习二
Executor接口
如果查看jdk文档,会发现java线程池都源自于这个超级接口Executor,但是这个接口本身比较简单:
public interface Executor { /** 在未来某个时间执行给定的命令。该命令可能在新的线程、已入池的线程或者正调用的线程中执行, 这由 Executor 实现决定。 * * @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); }
可以看到Executor 中只有一个execute 方法。此接口提供一种将任务提交与每个任务将如何运行的机制分离开来的方法,相比较为每个人物调用new Thread(Runnable r).start() ,我们更偏向于使用Executor (执行器)来运行任务:
Executor executor = anExecutor; executor.execute(new RunnableTask1()); executor.execute(new RunnableTask2()); ...
实现一个执行器也很简单:
class ThreadPerTaskExecutor implements Executor { public void execute(Runnable r) { new Thread(r).start(); } }ExecutorService接口
Executor 提供的方法太少了!根本不能满足日常所需,而从它派生下来的接口ExecutorService 则显得更通用,毕竟它也是个Service。
public interface ExecutorService extends Executor { void shutdown(); ListshutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; Future submit(Callable task); Future submit(Runnable task, T result); Future> submit(Runnable task); List > invokeAll(Collection extends Callable > tasks) throws InterruptedException; T invokeAny(Collection extends Callable > tasks) throws InterruptedException, ExecutionException; ... }
可以看到,ExecutorService 接口中包含了我们平常使用的线程池的绝大多数方法,其中的一些方法在上文已经介绍过了。
AbstractExecutorServiceAbstractExecutorService是一个抽象类,并且实现了ExecutorService接口。
public abstract class AbstractExecutorService implements ExecutorService
在这个类中,提供了ExecutorService 一些方法的默认实现,比如submit ,invokeAll ,首先看submit 的实现:
publicFuture submit(Callable task) { if (task == null) throw new NullPointerException(); RunnableFuture ftask = newTaskFor(task); execute(ftask); return ftask; }
其中使用了newTaskFor 方法:
protectedRunnableFuture newTaskFor(Callable callable) { return new FutureTask (callable); }
newTaskFor 方法只是简单的将给定可调用任务包装成一个RunnableFuture ,使其具有取消运行的特性。而submit 中直接将任务交给execute() 运行.
再来看invokeAll() :
publicList > invokeAll(Collection extends Callable > tasks) throws InterruptedException { if (tasks == null) throw new NullPointerException(); //创建一个list保存所有的结果 List > futures = new ArrayList >(tasks.size()); boolean done = false; try { for (Callable t : tasks) { RunnableFuture f = newTaskFor(t); futures.add(f); execute(f); //运行任务 } for (Future f : futures) { if (!f.isDone()) { //依次取结果 try { f.get(); //这里使用get是为了等待运行完成,如果没完成就会阻塞 } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } } } done = true; return futures; } finally { if (!done) //如果发生异常,则取消所有任务 for (Future f : futures) f.cancel(true); } }
续:java线程池的原理学习(二)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/64434.html
摘要:接上文线程池的原理学习二深入剖析线程池的五种状态类中将线程状态分为了以下五种可以接受新任务并且处理进入队列中的任务不接受新任务,但是仍然执行队列中的任务不接受新任务也不执行队列中的任务所有任务中止,队列为空,进入该状态下的任务会执行方法方法 接上文:java线程池的原理学习(二) ThreadPoolExecutor深入剖析 线程池的五种状态 ThreadPoolExecutor 类中...
摘要:当活动线程核心线程非核心线程达到这个数值后,后续任务将会根据来进行拒绝策略处理。线程池工作原则当线程池中线程数量小于则创建线程,并处理请求。当线程池中的数量等于最大线程数时默默丢弃不能执行的新加任务,不报任何异常。 spring-cache使用记录 spring-cache的使用记录,坑点记录以及采用的解决方案 深入分析 java 线程池的实现原理 在这篇文章中,作者有条不紊的将 ja...
摘要:接上文线程池的原理学习简单介绍,线程池类,继承自构造方法提供了四种构造方法实现这里只介绍一种有必要对每个参数解释一下池中所保存的线程数,包括空闲线程。文档中提供了一个可以暂停和恢复的线程池例子运行原理线程池的原理学习三 接上文:java线程池的原理学习 ThreadPoolExecutor简单介绍 ThreadPoolExecutor,线程池类,继承自 AbstractExecutor...
摘要:线程池的工作原理一个线程池管理了一组工作线程,同时它还包括了一个用于放置等待执行任务的任务队列阻塞队列。使用线程池可以对线程进行统一的分配和监控。线程池的注意事项虽然线程池是构建多线程应用程序的强大机制,但使用它并不是没有风险的。 线程池的工作原理一个线程池管理了一组工作线程, 同时它还包括了一个用于放置等待执行 任务的任务队列(阻塞队列) 。 一个线程池管理了一组工作线程, 同时它还...
摘要:每个通过网络到达服务器的连接都被包装成一个任务并且传递给线程池。线程池的线程会并发的处理连接上的请求。用线程池控制线程数量,其他线程排队等候。实现包,线程池顶级接口是但是严格意义讲并不是一个线程。此线程池支持定时以及周期性执行任务的需求。 tutorial site1tutorial site2 一个问题: 每启动一个新线程都会有相应的性能开销(涉及到OS的交互:创建线程,销毁线程...
阅读 3896·2021-09-09 09:33
阅读 1737·2021-09-06 15:14
阅读 1899·2019-08-30 15:44
阅读 3046·2019-08-29 18:36
阅读 3734·2019-08-29 16:22
阅读 2076·2019-08-29 16:21
阅读 2510·2019-08-29 15:42
阅读 1630·2019-08-29 11:00