本次分享主要包括阻塞IO、非阻塞IO、异步IO的代码实现。
阻塞IO
首先我们来看下阻塞IO代码实现
阻塞IO服务类:
public class BioServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9000);
while (true) {
Socket socket = serverSocket.accept();
new Thread(() -> {
try {
while (true) {
byte[] bytes = new byte[1024];
int read = socket.getInputStream().read(bytes);
System.out.println("从客户端" + socket.getPort() + "读到的内容:" + new String(bytes, 0, read));
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
}
客户端类:
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 9000);
Scanner scanner = new Scanner(System.in);
String line = null;
while ((line = scanner.next()) != null) {
socket.getOutputStream().write(line.getBytes());
}
}
}
流程图:
非阻塞IO
先来看下不使用selector的实现
public class NioServer {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9000));
serverSocketChannel.configureBlocking(false);
while(true) {
SocketChannel socketChannel = serverSocketChannel.accept();
if (socketChannel != null) {
new Thread(() -> {
try {
socketChannel.configureBlocking(false);
while (true) {
ByteBuffer byteBuffer = ByteBuffer.allocate(126);
int read = socketChannel.read(byteBuffer);
if (read > 0) {
byteBuffer.flip();
byte[] bytes = new byte[read];
byteBuffer.get(bytes, 0, read);
String content = new String(bytes);
System.out.println("从客户端读到内容:" + content);
}
Thread.sleep(1);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
}
下面是带selector的实现
public class NioSelectorServer {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9000));
serverSocketChannel.configureBlocking(false);
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
int select = selector.select();
System.out.println("select : " + select);
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
if (selectionKey.isAcceptable()) {
ServerSocketChannel serverSocket = (ServerSocketChannel)selectionKey.channel();
SocketChannel socketChannel = serverSocket.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
SocketChannel socket = (SocketChannel)selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(126);
int read = socket.read(byteBuffer);
if (read > 0) {
byte[] bytes = new byte[read];
byteBuffer.flip();
byteBuffer.get(bytes, 0, read);
String content = new String(bytes);
System.out.println("读到客户端" + socket.socket().getPort() + "传输的数据:" + content);
}
}
}
}
}
}
流程图:
异步IO
最后再来看看异步IO的实现
public class AioServer {
public static void main(String[] args) throws IOException, InterruptedException {
AsynchronousServerSocketChannel aioServerSocketChannel = AsynchronousServerSocketChannel.open();
aioServerSocketChannel.bind(new InetSocketAddress(9000));
aioServerSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
aioServerSocketChannel.accept(attachment, this);
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
socketChannel.read(byteBuffer, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
byteBuffer.flip();
System.out.println("从客户端读到内容:" + new String(byteBuffer.array(), 0 ,result));
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
}
});
Thread.sleep(Integer.MAX_VALUE);
}
}
BIO、NIO、AIO对比
BIO | NIO | AIO | |
IO模型 | 同步阻塞 | 同步非阻塞(多路复用) | 异步非阻塞 |
编程难度 | 简单 | 复杂 | 复杂 |
可靠性 | 差 | 好 | 好 |
吞吐量 | 低 | 高 | 高 |