今天趁闲暇,简单体验了下,简单分享如下:
关于AIO的概念理解
关于AIO的概念,仅谈谈个人的一点理解。可能不到位,请大家指出。
Io的两个重要步骤:发起IO请求,和实际的IO操作。在unix网络编程的定义里异步和非异步概念的区别就是实际的IO操作是否阻塞。如果不是就是异步,如果是就是同步。
而阻塞和非阻塞的区别在于发起IO请求的时候是否会阻塞,如果会就是阻塞,不会就是非阻塞。
本人理解能力有限,想了个例子来辅助自己理解:
小明想要买一本<深入java虚拟机>的书,以下几个场景可以来理解这几种io模式:
1.
2.
3.
售货员可以认为是操作系统的一个服务,而小明是一个用户进程。不知道是否有误,如果有误请大家拍砖指出,谢谢。
可以看出2,3的效率明显要比1高。但是1最简单,而2,3需要一些协作。充分证明了团队合作的力量。
JDK7 AIO初体验
AsynchronousChannel:支持异步通道,包括服务端AsynchronousServerSocket
CompletionHandler:用户处理器。定义了一个用户处理就绪事件的接口,由用户自己实现,异步io的数据就绪后回调该处理器消费或处理数据。
AsynchronousChannelGroup
以一个简单监听服务端为例,基本过程是:
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.AsynchronousServerSocket Channel; - import
java.nio.channels.AsynchronousSocketChanne l; - 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; -
-
- public
class AIOServer { -
public final static int PORT = 9888; -
private AsynchronousServerSocket Channel server; -
-
public AIOServer() throws IOException { -
server = AsynchronousServerSocket Channel.open().bind( -
new InetSocketAddress(PORT)); -
} -
-
public void startWithFuture() throws InterruptedException, -
ExecutionException, TimeoutException { -
System.out.println("Server listen on " + PORT); -
Future<AsynchronousSocketChanne l> future = server.accept(); -
AsynchronousSocketChanne l 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 startWithCompletionHandl er() throws InterruptedException, -
ExecutionException, TimeoutException { -
System.out.println("Server listen on " + PORT); -
//注册事件和事件完成后的处理器 -
server.accept(null, -
new CompletionHandler<AsynchronousSocketChanne l, Object>() { -
final ByteBuffer buffer = ByteBuffer.allocate(1024); -
-
public void completed(AsynchronousSocketChanne l 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().startWithCompletionHandl er(); -
} - }
AIOClient.java
- package
io.aio; -
- import
java.net.InetSocketAddress; - import
java.nio.ByteBuffer; - import
java.nio.channels.AsynchronousSocketChanne l; -
- public
class AIOClient { -
-
public static void main(String... args) throws Exception { -
AsynchronousSocketChanne l client = AsynchronousSocketChanne l.open(); -
client.connect(new InetSocketAddress("localhost", 9888)); -
client.write(ByteBuffer.wrap("test".getBytes())).get(); -
} - }
服务端写了两种处理实现方式,startWithCompletionHandl
从以上来看AIO的代码简单了很多,至少比NIO的代码实现简单很多。