一文带你搞懂Java的3种IO模型
在Java中,输入输出操作是很常见的。Java的IO模型可以分为三种:Blocking IO、Non-blocking IO和异步IO。它们的区别在于处理IO事件的方式不同。
Blocking IO
在Blocking IO模型中,当向Socket写入数据时,线程会阻塞,直到数据被真正写入。而当Socket读取数据时,线程也会阻塞,直到数据被真正读取。
Blocking IO模型的示例:
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BlockingIOServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
byte[] buffer = new byte[1024];
int length;
// 阻塞读取数据
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
// 阻塞写入数据
os.flush();
}
socket.close();
}
}
}
Non-blocking IO
在Non-blocking IO模型中,当向Socket写入数据时,线程不会阻塞,而是继续执行自己的任务。当数据真正写入后,会通知应用程序。当Socket读取数据时,也不会阻塞,而是立即返回一个状态信息,告诉应用程序是否有数据可读。
Non-blocking IO模型的示例:
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.io.IOException;
public class NonBlockingIOServer {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new java.net.InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
int numOfSelectedKeys = selector.select();
if (numOfSelectedKeys > 0) {
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey)it.next();
if (key.isAcceptable()) {
ServerSocketChannel sc = (ServerSocketChannel)key.channel();
SocketChannel clientChannel = sc.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel clientChannel = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
clientChannel.read(buffer);
buffer.flip();
clientChannel.write(buffer);
}
it.remove();
}
}
}
}
}
Async IO
在Async IO模型中,当向Socket写入数据时,线程会立即返回,不会阻塞,而是将数据存储到缓存中。当数据被真正写入后,操作系统会通知应用程序,告诉它数据已写入。当Socket读取数据时,也不会阻塞,而是立即返回,当数据被真正读取到缓存后,操作系统会通知应用程序。
Async IO模型需要使用Java NIO 2.0提供的AsynchronousChannel或CompletableFuture等API进行开发。
关于Async IO模型的示例,由于篇幅所限,本文不再进行详细说明,读者可以自行查找相关资料进行学习。
总结
本文介绍了Java的三种IO模型:Blocking IO、Non-blocking IO和异步IO,并给出了每种IO模型的示例说明。阅读本文后,希望读者可以更好地理解Java中的IO操作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文带你你搞懂Java的3种IO模型 - Python技术站