- 浏览: 999711 次
-
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
Executor接口的定义:http://donald-draper.iteye.com/blog/2365625
ExecutorService接口定义:http://donald-draper.iteye.com/blog/2365738
Future接口定义:http://donald-draper.iteye.com/blog/2365798
FutureTask解析:http://donald-draper.iteye.com/blog/2365980
CompletionService接口定义:http://donald-draper.iteye.com/blog/2366239
ExecutorCompletionService解析:http://donald-draper.iteye.com/blog/2366254
看这篇文章之前,对于没有接触过java并发包的朋友,建议将上面几个链接文章看完。
超时执行Callable任务集,与非超时执行任务集不同的点是,
第一点:在每次执行任务,判断是否超时,超时则返回结果集;
第二点:在等待线程任务结束时,为超时等待;
再来看InvokeAny方法:
invokeAny的任务集,主要通过ExecutorCompletionService去执行,
当有任务执行结束时,获取执行结果,并取消其他任务。
总结:
无论是提交Runnable任务,还是Callable都是创建FutureTask执行任务,然后执行,返回结果。执行Callable任务集,遍历任务集合,创建相应的RunnableFuture任务,并添加到结果集;遍历结果集,等待所有任务执行完。超时执行Callable任务集,与非超时执行任务集不同的点是,第一点:在每次执行任务,判断是否超时,超时则返回结果集;第二点:在等待线程任务结束时,为超时等待。invokeAny的任务集,主要通ExecutorCompletionService去执行,当有任务执行结束时,获取执行结果,并取消其他任务。
ExecutorService接口定义:http://donald-draper.iteye.com/blog/2365738
Future接口定义:http://donald-draper.iteye.com/blog/2365798
FutureTask解析:http://donald-draper.iteye.com/blog/2365980
CompletionService接口定义:http://donald-draper.iteye.com/blog/2366239
ExecutorCompletionService解析:http://donald-draper.iteye.com/blog/2366254
看这篇文章之前,对于没有接触过java并发包的朋友,建议将上面几个链接文章看完。
package java.util.concurrent; import java.util.*; /** * Provides default implementations of {@link ExecutorService} * execution methods. This class implements the <tt>submit</tt>, * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults * to the {@link FutureTask} class provided in this package. For example, * the implementation of <tt>submit(Runnable)</tt> creates an * associated <tt>RunnableFuture</tt> that is executed and * returned. Subclasses may override the <tt>newTaskFor</tt> methods * to return <tt>RunnableFuture</tt> implementations other than * <tt>FutureTask</tt>. * AbstractExecutorService提供了ExecutorService执行方法的默认实现。 submit,invokeAny,invokeAll方法主要通过newTaskFor方法返回一个RunnableFuture ,默认为FutureTask。比如FutureTask方法创建一个关联的RunnableFuture,并返回。 子类可以重写newTaskFor方法,返回一个除FutureTask之外的RunnableFuture接口实现。 * <p> <b>Extension example</b>. Here is a sketch of a class * that customizes {@link ThreadPoolExecutor} to use * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>: 下面是一个ThreadPoolExecutor实现范例,用CustomTask代替默认的FutureTask。 * <pre> {@code * public class CustomThreadPoolExecutor extends ThreadPoolExecutor { * * static class CustomTask<V> implements RunnableFuture<V> {...} * * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) { * return new CustomTask<V>(c); * } * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) { * return new CustomTask<V>(r, v); * } * // ... add constructors, etc. * }}</pre> * * @since 1.5 * @author Doug Lea */ public abstract class AbstractExecutorService implements ExecutorService { /** * Returns a <tt>RunnableFuture</tt> for the given runnable and default * value. * 根据给定的Runnable和value,返回一个RunnableFuture,实际为FutureTask * @param runnable the runnable task being wrapped * @param value the default value for the returned future * @return a <tt>RunnableFuture</tt> which when run will run the * underlying runnable and which, as a <tt>Future</tt>, will yield * the given value as its result and provide for cancellation of * the underlying task. * @since 1.6 */ protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value); } /** * Returns a <tt>RunnableFuture</tt> for the given callable task. * 根据Callable,返回一个RunnableFuture,实际为FutureTask * @param callable the callable task being wrapped * @return a <tt>RunnableFuture</tt> which when run will call the * underlying callable and which, as a <tt>Future</tt>, will yield * the callable's result as its result and provide for * cancellation of the underlying task. * @since 1.6 */ protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); } /** 提交,执行一个返回值为void的Runnable任务 * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); //创建任务 RunnableFuture<Void> ftask = newTaskFor(task, null); //实际在Executor为抽象方法,待子类扩展 execute(ftask); return ftask; } /** 提交,执行一个返回值为T的Runnable任务,与submit(Runnable task)方法,基本没区别 * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ 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; } /** 提交,执行一个Callable任务 * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); //创建任务 RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; } //执行Callable任务集 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException { if (tasks == null) throw new NullPointerException(); List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); boolean done = false; try { //遍历任务集合,创建相应的RunnableFuture任务,并添加到结果集 for (Callable<T> t : tasks) { RunnableFuture<T> f = newTaskFor(t); futures.add(f); execute(f); } //遍历结果集,等待所有任务执行完 for (Future<T> f : futures) { if (!f.isDone()) { try { f.get(); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } } } done = true; //执行完,返回结果集 return futures; } finally { if (!done) //如果任务未执行完,遍历结果集,取消任务 for (Future<T> f : futures) f.cancel(true); } } //超时执行Callable任务集 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException { if (tasks == null || unit == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); boolean done = false; try { for (Callable<T> t : tasks) futures.add(newTaskFor(t)); long lastTime = System.nanoTime(); //与非超时执行任务集不同的点是,在每次执行任务,判断是否超时,超时则返回结果集 // Interleave time checks and calls to execute in case // executor doesn't have any/much parallelism. Iterator<Future<T>> it = futures.iterator(); while (it.hasNext()) { execute((Runnable)(it.next())); long now = System.nanoTime(); nanos -= now - lastTime;//nanos = nanos - (now - lastTime),剩下超时时间 lastTime = now; if (nanos <= 0) return futures; } for (Future<T> f : futures) { if (!f.isDone()) { if (nanos <= 0) return futures; try { //另一个不同点,为超时等待任务线程执行完 f.get(nanos, TimeUnit.NANOSECONDS); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } catch (TimeoutException toe) { return futures; } long now = System.nanoTime(); nanos -= now - lastTime;//nanos = nanos - (now - lastTime),剩下超时时间 lastTime = now; } } done = true; return futures; } finally { if (!done) for (Future<T> f : futures) f.cancel(true); } } }
超时执行Callable任务集,与非超时执行任务集不同的点是,
第一点:在每次执行任务,判断是否超时,超时则返回结果集;
第二点:在等待线程任务结束时,为超时等待;
再来看InvokeAny方法:
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)); } /** * 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(); List<Future<T>> futures= new ArrayList<Future<T>>(ntasks); 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; long lastTime = timed ? System.nanoTime() : 0; Iterator<? extends Callable<T>> it = tasks.iterator(); // Start one task for sure; the rest incrementally //确保有一个任务在执行,余下的自动增长 futures.add(ecs.submit(it.next())); //剩余任务数量自减,任务激活数量赋1 --ntasks; int active = 1; for (;;) { //从完成任务执行器poll一个任务结果,这个我们在ExecutorCompletionService, //那篇文章中,有说,这里不再说 Future<T> f = ecs.poll(); if (f == null) { //如果没有任务完成,则提交任务到执行器,剩余任务数量自减,任务激活数量自增 if (ntasks > 0) { --ntasks; futures.add(ecs.submit(it.next())); ++active; } else if (active == 0) //如果所有任务已经在跑,且激活数量任务数量为0,则跳出自旋 break; else if (timed) { //如果是超时,则超时poll f = ecs.poll(nanos, TimeUnit.NANOSECONDS); if (f == null) throw new TimeoutException(); long now = System.nanoTime(); //重新计算剩余超时时间 nanos -= now - lastTime; lastTime = now; } 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 (Future<T> f : futures) //取消完成的任务 f.cancel(true); } }
invokeAny的任务集,主要通过ExecutorCompletionService去执行,
当有任务执行结束时,获取执行结果,并取消其他任务。
总结:
无论是提交Runnable任务,还是Callable都是创建FutureTask执行任务,然后执行,返回结果。执行Callable任务集,遍历任务集合,创建相应的RunnableFuture任务,并添加到结果集;遍历结果集,等待所有任务执行完。超时执行Callable任务集,与非超时执行任务集不同的点是,第一点:在每次执行任务,判断是否超时,超时则返回结果集;第二点:在等待线程任务结束时,为超时等待。invokeAny的任务集,主要通ExecutorCompletionService去执行,当有任务执行结束时,获取执行结果,并取消其他任务。
发表评论
-
Executors解析
2017-04-07 14:38 1294ThreadPoolExecutor解析一(核心线程池数量、线 ... -
ScheduledThreadPoolExecutor解析三(关闭线程池)
2017-04-06 20:52 4484ScheduledThreadPoolExecutor解析一( ... -
ScheduledThreadPoolExecutor解析二(任务调度)
2017-04-06 12:56 2164ScheduledThreadPoolExecutor解析一( ... -
ScheduledThreadPoolExecutor解析一(调度任务,任务队列)
2017-04-04 22:59 5020Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析四(线程池关闭)
2017-04-03 23:02 9150Executor接口的定义:http: ... -
ThreadPoolExecutor解析三(线程池执行提交任务)
2017-04-03 12:06 6115Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析二(线程工厂、工作线程,拒绝策略等)
2017-04-01 17:12 3061Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析一(核心线程池数量、线程池状态等)
2017-03-31 22:01 20572Executor接口的定义:http://donald-dra ... -
ScheduledExecutorService接口定义
2017-03-29 12:53 1551Executor接口的定义:http://donald-dra ... -
ExecutorCompletionService解析
2017-03-28 14:27 1624Executor接口的定义:http://donald-dra ... -
CompletionService接口定义
2017-03-28 12:39 1092Executor接口的定义:http://donald-dra ... -
FutureTask解析
2017-03-27 12:59 1360package java.util.concurrent; ... -
Future接口定义
2017-03-26 09:40 1231/* * Written by Doug Lea with ... -
ExecutorService接口定义
2017-03-25 22:14 1189Executor接口的定义:http://donald-dra ... -
Executor接口的定义
2017-03-24 23:24 1715package java.util.concurrent; ... -
简单测试线程池拒绝执行任务策略
2017-03-24 22:37 2060线程池多余任务的拒绝执行策略有四中,分别是直接丢弃任务Disc ... -
JAVA集合类简单综述
2017-03-23 22:51 946Queue接口定义:http://donald-draper. ... -
DelayQueue解析
2017-03-23 11:00 1766Queue接口定义:http://donald-draper. ... -
SynchronousQueue解析下-TransferQueue
2017-03-22 22:20 2188Queue接口定义:http://donald-draper. ... -
SynchronousQueue解析上-TransferStack
2017-03-21 22:08 3125Queue接口定义:http://donald-draper. ...
相关推荐
美团动态线程池实践思路开源项目(DynamicTp)线程池源码解析及通知告警篇 本文详细介绍了美团动态线程池实践思路开源项目(DynamicTp)的通知告警模块,该模块提供了多种通知告警功能,每一个通知项都可以独立配置...
* AbstractExecutorService是Java中的抽象线程池类,提供了execute()和submit()方法的默认实现。 七、高并发编程的其他知识点 * volatile关键字可以确保变量的可见性和原子性。 * synchronized关键字可以确保方法...
19. **AbstractExecutorService**:提供了ExecutorService执行方法的默认实现,是线程池服务的基础。 20. **AbstractHttpClient**:这是HttpClient的便利基类,用于HTTP客户端的实现,简化了网络请求的处理。 21. ...
ForkJoinPool是这个框架的核心组件,它扩展了AbstractExecutorService类,并实现了工作窃取算法。工作窃取算法允许工作线程在自己的任务队列为空时,从其他线程的任务队列中偷取任务来执行,这样可以更高效地利用...
- **Executor→ExecutorService→AbstractExecutorService→ThreadPoolExecutor**:这是线程池实现的基本层次结构,其中`ThreadPoolExecutor`是核心类,提供了线程池的核心功能。 - **工具类Executors**: 类似于`...
《深入解析Java线程池:MyThreadPool》 在Java编程中,线程池是一种非常重要的并发处理机制。本文将深入探讨自定义线程池——MyThreadPool的实现原理、设计模式以及如何有效地使用线程池来优化系统性能。线程池通过...