读完了再通知我 AIO
AIO即为Asynchronized。异步IO, NIO只是newIO不是异步的,只是同步可以设置为非阻塞模式 ,真正异步的是AIO。AIO将Future模式运用的十分广泛,它不是等待IO准备好后再通知线程。而是等待IO操作完成后再通知线程,实现异步IO。
AIO来实现服务器
异步IO需要使用异步通道AsynchronousServerSocketChannel。
1 | package thread.test.concurrent.aio; |
AIO Echo客户端实现
在服务端的实现中。我们使用Future.get()方法将异步调用转为了一个同步等待。在客户端的实现里,我们将全部使用异步回调的实现。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74package thread.test.concurrent.aio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
/**
* AIO客户端
* @author 圈圈
* @version 1.0
*/
public class AIOClient {
public static void main(String[] args) throws Exception {
try {
//构建客户端socketChannel对象
final AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
client.connect(new InetSocketAddress("127.0.0.1", 8888), null, new CompletionHandler<Void, Object>() {
//同理返回 连接成功和失败回调函数 所有操作均是完全异步的执行很快不会等待
public void completed(Void result, Object attachment) {
// TODO Auto-generated method stub
//往服务端写数据也会有回调方法
client.write(ByteBuffer.wrap(new String("Hello Server !").getBytes()), null, new CompletionHandler<Integer, Object>() {
public void completed(Integer result, Object attachment) {
//构建用于读取服务端的bytebuff
ByteBuffer buff = ByteBuffer.allocate(1024);
//从服务端读取写回的数据 arg2位置不要为null
client.read(buff, buff, new CompletionHandler<Integer, ByteBuffer>() {
public void completed(Integer result, ByteBuffer buff) {
buff.flip();
try {
//读取客户端发来的信息
System.out.println("Server :"+new String(buff.array()).trim());
//关闭客户端 异步操作很快
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void failed(Throwable exc, ByteBuffer attachment) {
}
});
}
public void failed(Throwable exc, Object attachment) {
// TODO Auto-generated method stub
}
});
}
public void failed(Throwable exc, Object attachment) {
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//由于主线程马上休息 这里等待上述处理全部完成即可
Thread.sleep(5000);
}
}