java并发编程框架 Executor ExecutorService invokeall
首先介绍两个重要的接口,Executor和ExecutorService,定义如下:
- public interface Executor {
- void execute(Runnable command);
- }
- public interface ExecutorService extends Executor {
- //不再接受新任务,待所有任务执行完毕后关闭ExecutorService
- void shutdown();
- //不再接受新任务,直接关闭ExecutorService,返回没有执行的任务列表
- List<Runnable> shutdownNow();
- //判断ExecutorService是否关闭
- boolean isShutdown();
- //判断ExecutorService是否终止
- boolean isTerminated();
- //等待ExecutorService到达终止状态
- boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
- <T> Future<T> submit(Callable<T> task);
- //当task执行成功的时候future.get()返回result
- <T> Future<T> submit(Runnable task, T result);
- //当task执行成功的时候future.get()返回null
- Future<?> submit(Runnable task);
- //批量提交任务并获得他们的future,Task列表与Future列表一一对应
- <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
- throws InterruptedException;
- //批量提交任务并获得他们的future,并限定处理所有任务的时间
- <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;
- }
为了配合使用上面的并发编程接口,有一个Executors工厂类,负责创建各类满足ExecutorService接口的线程池,具体如下:
newFixedThreadPool:创建一个固定长度的线程池,线程池中线程的数量从1增加到最大值后保持不变。如果某个线程坏死掉,将会补充一个新的线程。
newCachedThreadPool:创建长度不固定的线程池,线程池的规模不受限制,不常用。
newSingleThreadExecutor:创建一个单线程的Executor,他其中有一个线程来处理任务,如果这个线程坏死掉,将补充一个新线程。
newScheduledThreadPool:创建固定长度的线程池,以延时或定时的方式来执行任务。
下面是Executor和ExecutorService中常用方法的示例:
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Iterator;
- import java.util.List;
- import java.util.concurrent.Callable;
- import java.util.concurrent.Executor;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- import java.util.concurrent.TimeUnit;
- public class Demo{
- public static void main(String [] args){
- //--------Executor示例------------//
- Executor s=Executors.newSingleThreadExecutor();
- s.execute(new MyRunnableTask("1"));
- //--------ExecutorService示例------------//
- ExecutorService es=Executors.newFixedThreadPool(2);
- //--------get()示例------------//
- Future<String> future=es.submit(new MyCallableTask("10"));
- try{
- System.out.println(future.get());
- }catch(Exception e){}
- //--------get(timeout, timeunit)示例------------//
- future=es.submit(new MyCallableTask("11"));
- try{
- System.out.println(future.get(500,TimeUnit.MILLISECONDS));
- }catch(Exception e){
- System.out.println("cancle because timeout");
- }
- //--------invokeAll(tasks)示例------------//
- List<MyCallableTask> myCallableTasks=new ArrayList<MyCallableTask>();
- for(int i=0;i<6;i++){
- myCallableTasks.add(new MyCallableTask(i+""));
- }
- try {
- List<Future<String>> results = es.invokeAll(myCallableTasks);
- Iterator<Future<String>> iterator=results.iterator();
- while(iterator.hasNext()){
- future=iterator.next();
- System.out.println(future.get());
- }
- } catch (Exception e) {}
- //--------invokeAll(tasks,timeout,timeunit))示例------------//
- try {
- //限定执行时间为2100ms,每个任务需要1000ms,线程池的长度为2,因此最多只能处理4个任务。一共6个任务,有2个任务会被取消。
- List<Future<String>> results = es.invokeAll(myCallableTasks,2100,TimeUnit.MILLISECONDS);
- Iterator<Future<String>> iterator=results.iterator();
- while(iterator.hasNext()){
- future=iterator.next();
- if(!future.isCancelled())
- System.out.println(future.get());
- else
- System.out.println("cancle because timeout");
- }
- } catch (Exception e) {}
- es.shutdown();
- }
- }
- class MyRunnableTask implements Runnable{
- private String name;
- public MyRunnableTask(String name) {
- this.name=name;
- }
- @Override
- public void run() {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("runnable task--"+name);
- }
- }
- class MyCallableTask implements Callable<String>{
- private String name;
- public MyCallableTask(String name) {
- this.name=name;
- }
- @Override
- public String call() throws Exception {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {}
- StringBuilder sb=new StringBuilder("callable task--");
- return sb.append(name).toString();
- }
- }
上面的ExecutorSerivce接口中的invokeAll(tasks)方法用于批量执行任务,并且将结果按照task列表中的顺序返回。此外,还存在一个批量执行任务的接口CompletionTask。ExecutorCompletionService是实现CompletionService接口的一个类,该类的实现原理很简单:
用Executor类来执行任务,同时把在执行任务的Future放到BlockingQueue<Future<V>>队列中。该类实现的关键就是重写FutureTask类的done()方法,FutureTask类的done()方法是一个钩子函数(关于钩子函数,请读者自行查询),done()方法在FutureTask任务被执行的时候被调用。
ExecutorCompletionService类的核心代码如下:
- public Future<V> submit(Runnable task, V result) {
- if (task == null) throw new NullPointerException();
- RunnableFuture<V> f = newTaskFor(task, result);
- executor.execute(new QueueingFuture(f));
- return f;
- }
- private class QueueingFuture extends FutureTask<Void> {
- QueueingFuture(RunnableFuture<V> task) {
- super(task, null);
- this.task = task;
- }
- protected void done() { completionQueue.add(task); }
- private final Future<V> task;
- }
其中的done()方法定义如下:
- /**
- * Protected method invoked when this task transitions to state
- * <tt>isDone</tt> (whether normally or via cancellation). The
- * default implementation does nothing. Subclasses may override
- * this method to invoke completion callbacks or perform
- * bookkeeping. Note that you can query status inside the
- * implementation of this method to determine whether this task
- * has been cancelled.
- */
- protected void done() { }
ExecutorCompletionService的使用示例如下:
- import java.util.concurrent.Callable;
- import java.util.concurrent.CompletionService;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.ExecutorCompletionService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- public class Demo{
- public static void main(String [] args) throws InterruptedException, ExecutionException{
- CompletionService<String> cs=new ExecutorCompletionService<String>(
- Executors.newFixedThreadPool(2));
- for(int i=0;i<6;i++){
- cs.submit(new MyCallableTask(i+""));
- }
- for(int i=0;i<6;i++){
- Future<String> future=cs.take();
- //Retrieves and removes the Future representing the next completed task,
- //waiting if none are yet present.
- System.out.println(future.get());
- }
- }
- }
- class MyCallableTask implements Callable<String>{
- private String name;
- public MyCallableTask(String name) {
- this.name=name;
- }
- @Override
- public String call() throws Exception {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {}
- StringBuilder sb=new StringBuilder("callable task--");
- return sb.append(name).toString();
- }
- }
java并发编程框架 Executor ExecutorService invokeall的更多相关文章
- java并发编程:Executor、Executors、ExecutorService
1.Executor和ExecutorService Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable comma ...
- Java并发编程--4.Executor框架
简介 Executor框架是启动,管理线程的API, 它的内部实现是线程池机制,它有很多好处,比如使任务提交和任务执行解耦合,防止this逃逸:它的主要API包括: Executor, Execut ...
- Java 并发编程——Executor框架和线程池原理
Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...
- Java 并发编程——Executor框架和线程池原理
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- Java并发编程 - Executor,Executors,ExecutorService, CompletionServie,Future,Callable
一.Exectuor框架简介 Java从1.5版本开始,为简化多线程并发编程,引入全新的并发编程包:java.util.concurrent及其并发编程框架(Executor框架). Executor ...
- Java并发编程(08):Executor线程池框架
本文源码:GitHub·点这里 || GitEE·点这里 一.Executor框架简介 1.基础简介 Executor系统中,将线程任务提交和任务执行进行了解耦的设计,Executor有各种功能强大的 ...
- java并发编程-Executor框架
Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...
- (转)java并发编程--Executor框架
本文转自https://www.cnblogs.com/MOBIN/p/5436482.html java并发编程--Executor框架 只要用到线程,就可以使用executor.,在开发中如果需要 ...
随机推荐
- 【转载】__name__ == "__main__": 你认识我么?
<笨方法学Python>的习题50中,脚本ex50.py最后一行代码就是 if __name__ == "__main__": 那么,这句代码到底有什么用呢? 莫急莫急 ...
- PEiD 0.95 全插件中文绿色版
软件名称: PEiD 0.95 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win8 / Win7 / Vista / WinXP 软件大小: 4.4MB 图片预览: 软件简介: PEiD ...
- ArcGIS 10.5 named user介绍
1 Named user概述 1.1 Named user简介 Named user是ArcGIS产品自10.3版本正式推出的一种以用户为中心的授权机制,也称"授权 ...
- 学会Nodejs 的require和exports
NodeJs中模块的导入和导出,是最基本的概念,但是看了之后,心里还是有一些疑惑的地方,比如: 1.有两个文件:part.js 和 main.js,main.js中要想使用part.js中定义的变量和 ...
- iOS 打包上传AppStore相关(3)-iTunes相应配置以及使用蒲公英网站进行应用托管分发(链接/二维码)
上一篇讲到我们最终生成了一个格式为 .xcarchive 的文件(可以右键并Show in Finder)查看.本篇我们就进行最后的设置,打包上传.另外,还有一个小福利,那就是打测试包分发链接测试. ...
- Digi. Certificates: Key pairs usages
In short, we have some sort of algorithms to gen pair of private and public keys. The public key is ...
- 阻塞与非阻塞、同步与异步 I/O模型
I/O模型 Linux 下的五种I/O模型 阻塞I/O(blocking I/O) 非阻塞I/O (nonblocking I/O) I/O复用(select 和poll) (I/O multiple ...
- doc 窗口操作图
doc 窗口操作图doc 窗口操作图vdoc 窗口操作图
- 网页弹出窗口工具推荐之jqmodal
各种在jquery基础上实现的弹出窗口,有详细的开发说明文档.在项目中快速实现网页中弹出窗口的需求.基本能满足各种弹出窗口的需求 其官方网址如下http://jquery.iceburg.net/jq ...
- keycode 锁键盘按键(只能输入数字)
$('#lottoStage').keydown(function(){ if(event.keyCode == 46 || event.keyCode==8){ $(this).val(''); r ...