JDK1.7 AIO是异步非阻塞的,代码上AIO简化了NIO很多繁琐的实现。
对象 | 作用 |
---|---|
ExecutorService | 线程池 |
AsynchronousChannelGroup | 线程组 |
AsynchronousServerSocketChannel | AIO的server对象 |
CompletionHandler | 异步IO的处理模板 |
AIOServer.java
package cn.thinglin.aio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AIOServer {
//线程池
private ExecutorService executorService;
//线程组
private AsynchronousChannelGroup threadGroup;
//服务器通道
public AsynchronousServerSocketChannel assc;
public AIOServer(int port){
try {
//创建一个缓存池
executorService = Executors.newCachedThreadPool();
//创建线程组
threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
//创建服务器通道
assc = AsynchronousServerSocketChannel.open(threadGroup);
//进行绑定
assc.bind(new InetSocketAddress(port));
System.out.println("server start , port : " + port);
//accept不能使主线程阻塞
//CompletionHandler流处理对象
assc.accept(this, new CompletionHandler<AsynchronousSocketChannel, AIOServer>(){
@Override
public void completed(AsynchronousSocketChannel result, AIOServer attachment) {
attachment.assc.accept(attachment, this);//当有下一个客户端接入的时候 直接调用Server的accept方法,这样反复执行下去,保证多个客户端都可以阻塞
read(result);
}
@Override
public void failed(Throwable exc, AIOServer attachment) {
//连接失败
exc.printStackTrace();
}});
//阻塞主线程不让服务停止
Thread.sleep(Integer.MAX_VALUE);
} catch (Exception e) {
e.printStackTrace();
}
}
private void read(final AsynchronousSocketChannel asc) {
//读取数据
ByteBuffer buf = ByteBuffer.allocate(1024);
asc.read(buf, buf, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer resultSize, ByteBuffer attachment) {
//进行读取之后,重置标识位
attachment.flip();
//获得读取的字节数
System.out.println("Server -> " + "收到客户端的数据长度为:" + resultSize);
//获取读取的数据
String resultData = new String(attachment.array()).trim();
System.out.println("Server -> " + "收到客户端的数据信息为:" + resultData);
String response = "服务器响应, 收到了客户端发来的数据: " + resultData;
write(asc, response);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
}
private void write(AsynchronousSocketChannel asc, String response) {
try {
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.put(response.getBytes());
buf.flip();
asc.write(buf).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
AIOServer server = new AIOServer(8765);
}
}
AIOClient.java
package cn.thinglin.aio;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
public class AIOClient implements Runnable{
private AsynchronousSocketChannel asc ;
public AIOClient() throws Exception {
asc = AsynchronousSocketChannel.open();
}
public void connect(){
asc.connect(new InetSocketAddress("127.0.0.1", 8765));
}
public void write(String request){
try {
asc.write(ByteBuffer.wrap(request.getBytes())).get();
read();
} catch (Exception e) {
e.printStackTrace();
}
}
private void read() {
ByteBuffer buf = ByteBuffer.allocate(1024);
try {
asc.read(buf).get();
buf.flip();
byte[] respByte = new byte[buf.remaining()];
buf.get(respByte);
System.out.println(new String(respByte,"utf-8").trim());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
}
}
public static void main(String[] args) throws Exception {
AIOClient c1 = new AIOClient();
c1.connect();
AIOClient c2 = new AIOClient();
c2.connect();
AIOClient c3 = new AIOClient();
c3.connect();
new Thread(c1, "c1").start();
new Thread(c2, "c2").start();
new Thread(c3, "c3").start();
Thread.sleep(1000);
c1.write("c1 aaa");
c2.write("c2 bbbb");
c3.write("c3 ccccc");
}
}
image.png
网友评论