Java是一种流行的编程语言,广泛应用于各种软件开发、网站建设以及云平台应用等领域。在Java的网络编程中,主要有两种IO模式:Bio和Nio,它们分别代表着Blocking IO和Non-Blocking IO,下面我们来详细介绍一下这两种IO模式的概念。
public class BioServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8888); while (true) { Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); byte[] bytes = new byte[1024]; inputStream.read(bytes); String receiveMsg = new String(bytes, 0, bytes.length); System.out.println(receiveMsg); } } catch (IOException e) { e.printStackTrace(); } } }
BIo是同步阻塞IO模式,是指在执行IO操作时,该线程会阻塞,直到IO操作完成才会返回。在Bio中,如果客户端连接大量增加,服务器往往需要为每个连接都分配一个线程去处理,这样极大地浪费了服务器的资源,导致应用程序性能低下。
public class NioServer { public static void main(String[] args) { try { Selector selector = Selector.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress("localhost",8888)); serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iterator = keys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); if (key.isAcceptable()) { ServerSocketChannel serverSocket = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = serverSocket.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); System.out.println("connection elicit"); } else if (key.isReadable()) { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); socketChannel.read(buffer); String receiveMsg = new String(buffer.array()); System.out.println(receiveMsg); } iterator.remove(); } } } catch (IOException e) { e.printStackTrace(); } } }
Nio是同步非阻塞IO模式,是指在执行IO操作时,不会阻塞当前线程,而是利用IO多路复用的机制,将多个IO操作交给一个线程处理,大大减少了线程的数量。在Nio中,如果客户端连接大量增加,服务器仍然只需要一个线程去处理其IO操作,节省了服务器的资源,提高了应用程序的性能。
从上面的代码中可以看到,Nio模式中使用的是Selector选择器,它可以监视多个通道是否有数据可读或可写。另外,在Nio模式中,使用ByteBuffer来读取和写入数据,这些读写操作是异步执行的,不会阻塞当前线程。