浅析Java CompletionService

JDK的CompletionService提供了一种将生产新的异步任务与使用已完成任务的结果分离开来的服务,生产者 submit 执行的任务。使用者 take 已完成的任务,并按照完成这些任务的顺序处理它们的结果。例如,CompletionService 可以用来管理异步 IO ,执行读操作的任务作为程序或系统的一部分提交,然后,当完成读操作时,会在程序的不同部分执行其他操作,执行操作的顺序可能与所请求的顺序不同。

举个例子:现在要向服务器发送HTTP请求,服务端对于每个请求都需要做很多额外操作,很消耗时间,则可以将每个请求接受之后,提交到CompletionService异步处理,等执行完毕之后,在返回给客户端

package com.yf.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CompletionServiceTest {
	private ExecutorService threadPool = Executors.newCachedThreadPool();
	private CompletionService<Response> completionService = new ExecutorCompletionService<Response>(
			Executors.newCachedThreadPool());

	public CompletionServiceTest() {
		new Thread() {
			public void run() {
				while (true) {
					try {
						Future<Response> f = completionService.take();
						/**
						 * 获取响应信息,返回给客户端
						 * 如果completionService任务队列为空,此处将阻塞
						 */
						Response resp = f.get();
						System.out.println(resp.getId());
					} catch (Exception e) {
						System.out.println("Exception happened:"+e.getMessage());
					}
				}
			};
		}.start();
	}

	class Request{
		private int rid;
		private String body;
		public int getRid() {
			return rid;
		}
		public void setRid(int rid) {
			this.rid = rid;
		}
		public String getBody() {
			return body;
		}
		public void setBody(String body) {
			this.body = body;
		}
	}
	
	class Response {
		private int id;
		private String body;
		public int getId() {
			return id;
		}
		public void setId(int id) {
			this.id = id;
		}
		public String getBody() {
			return body;
		}
		public void setBody(String body) {
			this.body = body;
		}
	}

	class HTTPExecutor {
		public Future<Response> execute(final Request request) {
			Future<Response> f = threadPool.submit(new Callable<Response>() {
				public Response call() throws Exception {
					Response response = new Response();
					Thread.currentThread().sleep(3000);
					response.setId(request.getRid());
					response.setBody("response");
					return response;
				}
			});
			return f;
		}
	}

	public void submitHTTP(final Request request) {
		completionService.submit(new Callable<Response>() {
			public Response call() throws Exception {
				return new HTTPExecutor().execute(request).get();
			}
		});

	}

	public static void main(String[] args) {
		
		CompletionServiceTest t = new CompletionServiceTest();
		for (int i = 0; i < 10; i++) {
			/**
			 * 发送10个HTTP请求
			 */
			Request request =t.new Request();
			request.setRid(i);
			request.setBody("request");
			t.submitHTTP(request);
		}

	}

}

可以简单查看一下CompletionService的唯一实现类ExecutorCompletionService源码

关键代码如下:

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>>();
    }
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 QueueingFuture(f));
        return f;
    }

通过ExecutorCompletionService的构造器可知,CompletionService 依赖于一个单独的 Executor 来实际执行任务,内部管理了一个阻塞队列来,在调用submit方法时,会向创建一个新的RunnableFuture,然后异步执行该RunnableFuture,当其状态变为done后,添加CompletionService的阻塞队列中,外部通过调用take()(阻塞)或者poll()(非阻塞,为空返回null)方法获取执行结果。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Project基本知识培训资料 Project基本知识培训资料全文共34页,当前为第1页。 前 言 Project2010是一款集实用性、功能性与灵活性于一体的项目管理软件,它不仅具有强大的报表及灵活的项目管理工具,而且具有团队协同作业的功能。 通过本次Project2010管理软件的操作培训,可以帮助用户完全掌握项目管理与Project2010的基础知识,为计划管理工作的规范化提供必要的基础平台。 Project基本知识培训资料全文共34页,当前为第2页。 1 Project2010的工作界面 快速访问工具栏 选项卡 组 窗口控制按钮 全选按钮 行标题 域标题 时间刻度 Project基本知识培训资料全文共34页,当前为第3页。 2 设置工作时间 Project基本知识培训资料全文共34页,当前为第4页。 3 设置项目基本信息 3.1 更改任务信息 Project基本知识培训资料全文共34页,当前为第5页。 3 设置项目基本信息 3.2 更改任务生成模式 Project基本知识培训资料全文共34页,当前为第6页。 4 输入任务 Project基本知识培训资料全文共34页,当前为第7页。 5 编辑任务 5.1 复制任务 快捷键法 选择需要复制的任务的行,按Ctrl+C组合键复制任务。然后,选择放置复制任务的位置,按Ctrl+V组合键粘贴任务。 右击法 选择需要复制的任务行,按鼠标右键执行【复制】命令。然后,选择放置复制任务的位置,按鼠标右键执行【粘贴】命令。 5.2 移动任务 快捷键法 选择需要移动的任务的行,按Ctrl+X组合键复制任务。然后,选择放置复制任务的位置,按Ctrl+V组合键粘贴任务。 右击法 选择需要复制的任务行,按鼠标右键执行【剪切】命令。然后,选择放置复制任务的位置,按鼠标右键执行【粘贴】命令。 5.3 插入任务 右击法 选择要在其上方插入新任务的任务行,按鼠标右键执行【插入任务】命令。然后,选择放置复制任务的位置,按鼠标右键执行【粘贴】任务。 Project基本知识培训资料全文共34页,当前为第8页。 6 文档的保存及加密 6.1 文档的保存 Project基本知识培训资料全文共34页,当前为第9页。 6 文档的保存及加密 6.2 文档的加密 Project基本知识培训资料全文共34页,当前为第10页。 7 课堂练习 创建"邦泰国际"工程计划 序号 项目名称 工期 1 基础阶段 1.1 土方开挖 20天 1.2 人工挖孔桩及桩基检测 25天 1.3 承台及筏板基础 15天 1.4 地下室负一层墙柱及±0.00顶板 15天 1.5 现场临舍及办公区域 1.5.1 现场临舍及办公区域地面 5天 1.5.2 现场临舍及办公区域搭建 5天 1.6 边坡治理 20天 2 主体阶段 2.1 主体结构1-10层 70天 2.2 主体结构1-10层验收 5天 2.3 主体结构11-20层 70天 2.4 屋面结构 15天 2.5 主体结构验收 5天 2.6 砌体样板点评 10天 2.7 砌体工程1-20层 120天 Project基本知识培训资料全文共34页,当前为第11页。 8 组织任务 Project基本知识培训资料全文共34页,当前为第12页。 8 组织任务 8.1 摘要任务和子任务 Project基本知识培训资料全文共34页,当前为第13页。 8 组织任务 8.1 摘要任务和子任务 Project基本知识培训资料全文共34页,当前为第14页。 8 组织任务 8.2 WBS代码 Project基本知识培训资料全文共34页,当前为第15页。 8 组织任务 8.3 任务的相关性 项目中的任务需要相互关联,才能显示它们之间的关系和实施顺序,以确保项目的顺利完成。 任务之间的相关性是经过链接功能来创建的,在Project2010中,默认的链接任务为"完成-开始",除此之外,主要有以下链接类型: 链接类型 说明 示例 完成-开始(FS) 前置任务完成后,后续任务才开始 开始-开始(SS) 前置任务开始后,后续任务才开始 完成-完成(FF) 前置任务完成时,后续任务才完成 开始-完成(SF) 前置任务开始后,后续任务才可以完成 Project基本知识培训资料全文共34页,当前为第16页。 8 组织任务 8.4 创建任务链接(方法一) 快速创建默认链接 Project基本知识培训资料全文共34页,当前为第17页。 8 组织任务 8.4 创建任务链接(方法二) 其它链接类型的建立 Project基本知识培训资料全文共34页,当前为第18页。 8 组织任务 8.5 延迟或提前任务链接(一) Project基本知识培训资料全文共34页,当前为第19页。 8 组织任务 8.5 延迟或提前任务链接(二) Project基本知识培训资料全文
SDIO是一种用于连接多种设备的接口标准,包括Wi-Fi等无线网络设备。SDIO接口Wi-Fi驱动程序是用来管理和控制SDIO模块连接Wi-Fi设备的程序。Wi-Fi驱动程序通常是由设备制造商或操作系统供应商提供的,它们可以针对特定的SDIO模块和Wi-Fi设备进行定制。驱动程序管理SDIO接口与Wi-Fi设备的通信,控制数据流和网络连接以及提供对Wi-Fi设备的配置和监视功能。 在SDIO接口中,Wi-Fi设备一般作为一个SDIO卡出现,并通过SDIO总线与主处理器通信。因此,SDIO接口Wi-Fi驱动程序需要充分考虑SDIO总线和Wi-Fi设备之间的交互,并提供相应的操作和处理流程。常见的SDIO接口Wi-Fi驱动程序包括驱动层和协议层两部分。驱动层主要负责设备驱动程序的加载和卸载,以及控制SDIO总线与Wi-Fi设备之间的基本交互。协议层则实现与Wi-Fi设备之间的高级通信协议和数据传输,如TCP/IP协议栈、接入控制和传输协议等。 SDIO接口Wi-Fi驱动程序的设计和实现需要考虑多方面的因素,如SDIO总线的带宽和时序控制、Wi-Fi设备的固件和驱动程序兼容性、网络连接和性能要求等。通常需要经过严格的测试和优化才能实现良好的性能和稳定性。 总之,SDIO接口Wi-Fi驱动程序是一项关键技术,它的实现对Wi-Fi设备的性能和可靠性都有着重要的影响。需要专业的技术团队和优秀的开发工具支持,才能实现高品质的SDIO接口Wi-Fi驱动程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yangfeiblog

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值