文档章节

JDK 7 AIO 初体验

鉴客
 鉴客
发布于 2011/08/18 12:49
字数 1130
阅读 1116
收藏 11
JDK

JDK7已经release一段时间了,有个重要的新特性是AIO。
今天趁闲暇,简单体验了下,简单分享如下:

关于AIO的概念理解 
关于AIO的概念,仅谈谈个人的一点理解。可能不到位,请大家指出。
Io的两个重要步骤:发起IO请求,和实际的IO操作。在unix网络编程的定义里异步和非异步概念的区别就是实际的IO操作是否阻塞。如果是就是异步,如果不是就是同步。
而阻塞和非阻塞的区别在于发起IO请求的时候是否会阻塞,如果会就是阻塞,不会就是非阻塞。

本人理解能力有限,想了个例子来辅助自己理解:
小明想要买一本<深入java虚拟机>的书,以下几个场景可以来理解这几种io模式:
1.    如果小明每天都去书店问售货员说有没有这本书,如果没有就回去继续等待,等下次再过来文。(阻塞)
2.    如果小明告诉售货员想买一本<深入java虚拟机>的书,那么就在家里等着做其他事情去了,如果书到了售货员就通知小明,小明再自己过去取。
3.    如果小明告售货员想买一本<深入java虚拟机>的书,然后告诉售货员到了帮他送到某某地方去,就做其他事情去了。小明就不管了,等书到了,售货员就帮他送到那个地方了。


售货员可以认为是操作系统的一个服务,而小明是一个用户进程。不知道是否有误,如果有误请大家拍砖指出,谢谢。
可以看出2,3的效率明显要比1高。但是1最简单,而2,3需要一些协作。充分证明了团队合作的力量。

JDK7 AIO初体验 
AsynchronousChannel:支持异步通道,包括服务端AsynchronousServerSocketChannel和普通AsynchronousSocketChannel等实现。
CompletionHandler:用户处理器。定义了一个用户处理就绪事件的接口,由用户自己实现,异步io的数据就绪后回调该处理器消费或处理数据。
AsynchronousChannelGroup:一个用于资源共享的异步通道集合。处理IO事件和分配给CompletionHandler。(具体这块还没细看代码,后续再分析这块)

以一个简单监听服务端为例,基本过程是: 
1.    启动一个服务端通道
2.    定义一个事件处理器,用户事件完成的时候处理,如消费数据。
3.    向系统注册一个感兴趣的事件,如接受数据,并把事件完成的处理器传递给系统。
4.    都已经交待完毕,可以只管继续做自己的事情了,操作系统在完成事件后通过其他的线程会自动调用处理器完成事件处理。

以下用一个例子来简单实现,一个服务端和客户端。服务端监听客户端的消息,并打印出来。

AIOServer.java

package io.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 
 * @author noname
 */
public class AIOServer {
	public final static int PORT = 9888;
	private AsynchronousServerSocketChannel server;

	public AIOServer() throws IOException {
		server = AsynchronousServerSocketChannel.open().bind(
				new InetSocketAddress(PORT));
	}

	public void startWithFuture() throws InterruptedException,
			ExecutionException, TimeoutException {
		System.out.println("Server listen on " + PORT);
		Future<AsynchronousSocketChannel> future = server.accept();
		AsynchronousSocketChannel socket = future.get();
		ByteBuffer readBuf = ByteBuffer.allocate(1024);
		readBuf.clear();
		socket.read(readBuf).get(100, TimeUnit.SECONDS);
		readBuf.flip();
		System.out.printf("received message:" + new String(readBuf.array()));
		System.out.println(Thread.currentThread().getName());

	}

	public void startWithCompletionHandler() throws InterruptedException,
			ExecutionException, TimeoutException {
		System.out.println("Server listen on " + PORT);
		//注册事件和事件完成后的处理器
		server.accept(null,
				new CompletionHandler<AsynchronousSocketChannel, Object>() {
					final ByteBuffer buffer = ByteBuffer.allocate(1024);

					public void completed(AsynchronousSocketChannel result,
							Object attachment) {
						System.out.println(Thread.currentThread().getName());
						System.out.println("start");
						try {
							buffer.clear();
							result.read(buffer).get(100, TimeUnit.SECONDS);
							buffer.flip();
							System.out.println("received message: "
									+ new String(buffer.array()));
						} catch (InterruptedException | ExecutionException e) {
							System.out.println(e.toString());
						} catch (TimeoutException e) {
							e.printStackTrace();
						} finally {

							try {
								result.close();
								server.accept(null, this);
							} catch (Exception e) {
								System.out.println(e.toString());
							}
						}

						System.out.println("end");
					}

					@Override
					public void failed(Throwable exc, Object attachment) {
						System.out.println("failed: " + exc);
					}
				});
		// 主线程继续自己的行为
		while (true) {
			System.out.println("main thread");
			Thread.sleep(1000);
		}

	}

	public static void main(String args[]) throws Exception {
		new AIOServer().startWithCompletionHandler();
	}
}

AIOClient.java

package io.aio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;

public class AIOClient {

	public static void main(String... args) throws Exception {
		AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
		client.connect(new InetSocketAddress("localhost", 9888));
		client.write(ByteBuffer.wrap("test".getBytes())).get();
	}
}

服务端写了两种处理实现方式,startWithCompletionHandler是通过Handler来处理,startWithFuture是通过Future方式来处理。startWithCompletionHandler方法里可以看到调用accepte()完成异步注册后,线程就可以继续自己的处理了,完全不被这个io所中断。

从以上来看AIO的代码简单了很多,至少比NIO的代码实现简单很多。

 

本文转载自:http://www.iteye.com/topic/1113611

鉴客

鉴客

粉丝 953
博文 35
码字总数 1356
作品 0
长春
高级程序员
私信 提问
加载中

评论(2)

b
bovvie
楼上的是不是对异步IO有误解,你说的问题,根本不是问题吧
jingshishengxu
jingshishengxu
AIO 有两个问题
1:底层缓存(c代码部分的)大小被限制死了
2:一个socket连接一次只能投递一个请求,这样请求实际上还是同步的
talent-aio1.6.6 发布,再迎民间高手叫阵—代码当众大PK

web开发领域,springmvc之外有jfinal;TCP长连接领域,netty之外还有更易用的talent-aio 更好用、更接开发人员地气的TCP长连接框架,talent-aio 1.6.6正式版发布,已更新到maven中心仓库,t...

talent-tan
2017/03/20
2.6K
20
Java IO: BIO, NIO, AIO(含代码实现)

BIO, NIO, AIO,本身的描述都是在Java语言的基础上的。 而描述IO,我们需要从三个层面: 编程语言 实现原理 底层基础 从编程语言层面 BIO, NIO, AIO以Java的角度理解: BIO,同步阻塞式IO,简...

tantexian
2016/05/11
665
0
WebSocket服务器--CshBBrain

宝贝鱼(CshBBrain) 是一个来自中国的简单的轻量级的高性能的WebSocket服务器。支持服务器集群,能满足大并发量高容量的分布式系统开发。如果你需要开发带有集群功能的WebSocket服务器,宝贝鱼...

cshbbrain
2012/09/28
14.9K
17
java I/O 模型简述

同步与异步&阻塞与非阻塞 五大I/O模型详解 java I/O模型简述 概述 从同步与异步&阻塞与非阻塞的概念,到具体的I/O模型,再到具体的Java语言实现,都是层层递进,本篇就从Java语言来看I/O模型...

haoran_10
2016/07/14
619
5
Firefly 3.0.4 正式版发布,Java 的 Web 框架

Firefly 3.0.4 正式版发布。Firefly 3.0.4 切换jdk依赖到jdk7,使用jdk7新的j.u.c API提升了框架的整体性能。Firefly 网络层增加了 AIO 支持,并且为NIO和AIO提供了统一的抽象,网络框架可以...

Alvin0001
2014/12/18
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

手持式人证核验设备助力国家安全系统

手持式人证核验设备,是针对公共安全领域的移动化身份核验、追逃等需求推出的手持式一体化设备。其特点是具备人员信息采集、存储和比对功能,将采集到的人脸信息与居民身份证芯片中的人脸信息...

非思丸智能FaceTo
3分钟前
0
0
好程序员web前端教程分享JavaScript简写方法

今天好程序员web前端教程为大家分享JavaScript简写方法,小伙伴们快来看一看吧。 1.三元操作符 当想写if...else语句时,使用三元操作符来代替。 constx =20; let answer; if(x >10) { answer...

好程序员官网
7分钟前
1
0
PHP面试题2019年小米工程师面试题和答案解析

一、单选题(共29题,每题5分) 1.PHP面向对象方法重写描述错误的是? A、子类必须继承父类 B、子类可以重写父类已有方法 C、重写之后子类会调用父类方法 D、子类也可以具有与父类同名的属性...

一个PHP程序媛
10分钟前
0
0
K8s 从懵圈到熟练 – 镜像拉取这件小事

导读:相比 K8s 集群的其他功能,私有镜像的自动拉取,看起来可能是比较简单的。而镜像拉取失败,大多数情况下都和权限有关。所以,在处理相关问题的时候,我们往往会轻松的说:这问题很简单...

Mr_zebra
10分钟前
0
0
分布式锁简单入门以及实现方法

学过Java多线程的应该都知道什么是锁,没学过的也不用担心,Java中的锁可以简单的理解为多线程情况下访问临界资源的一种线程同步机制。 在学习或者使用Java的过程中进程会遇到各种各样的锁的...

yanlijun_java
13分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部