Java中io, nio和bio都是用于輸入輸出(IO)操作的。其中,輸入輸出(IO)是Java編程中重要的組成部分,取決于需要處理的數據以及用于解決問題的方法。
BIO,也就是Blocking IO,字面上就是阻塞IO,是Java IO最原始的模式,在新建線程時等待數據,這導致了它的效率比較低下。它的主要用途是在單個輸入/輸出線程中處理數據。使用Socket和ServerSocket時,它基本上是同步阻塞模式。在阻塞模式下,當線程讀取或寫入數據時,線程將被阻塞,直到所有數據被讀取或寫入為止。
public class BlockingServer { private int port; public static void main(String[] args) throws IOException { new BlockingServer(8080).run(); } private BlockingServer(int port) { this.port = port; } private void run() throws IOException { ServerSocket serverSocket = new ServerSocket(port); System.out.println("服務器已啟動,正在監聽" + port + "端口"); while (true) { Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String msg; while ((msg = reader.readLine()) != null) { System.out.println("客戶端發送的消息:" + msg); } socket.close(); } } }
NIO,則是Non-blocking IO,同樣可以翻譯為非阻塞IO。在Java 1.4中,一個新的包,java.nio被引入,并且成為Java IO功能的一個可被選用部分。NIO在BIO的基礎上進行了優化,采用單線程通過輪詢的方式,實現多個Channel(通道)的讀寫。NIO提供了Buffer來統一對數據的處理。
public class NioServer { private final int port; static final int BUFFER_SIZE = 1024; public static void main(String[] args) throws IOException { new NioServer(8080).run(); } public NioServer(int port) { this.port = port; } private void run() throws IOException { Selector selector = Selector.open(); ServerSocketChannel channel = ServerSocketChannel.open(); channel.configureBlocking(false); channel.socket().bind(new InetSocketAddress(port)); channel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("服務器已啟動,正在監聽" + port + "端口"); while (true) { int readyChannels = selector.select(); if (readyChannels == 0) { continue; } SetselectedKeys = selector.selectedKeys(); Iterator keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); int length = 0; while ((length = socketChannel.read(buffer)) >0) { buffer.flip(); System.out.println("客戶端發送的消息:" + Charset.forName("UTF-8").decode(buffer)); buffer.clear(); } } keyIterator.remove(); } } } }
最后,Java 7 還有一個Asynchronous I/O(AIO),也是非阻塞IO的一種形式,但在實現時被證明的不利于性能。