What is the difference between Java NIO and Java BIO?

1. What is Java NIO?

Synchronous non-blocking io mode, taking boiling water as an example, NIO's approach is to ask a thread to continuously poll the status of each kettle to see if the status of any kettle has changed, so as to proceed to the next step.

Java NIO has three major components: Buffer; Channel; Selector.

The question of when data is readable is achieved through the event-driven pattern. Channel: Equivalent to the carrier of IO operations, equivalent to a hardware device, a file, a socket or different IO operations in different programs, such as read, write.

A channel is similar to a stream, but it is a little different: it can both read data from the channel and write data to the channel. But stream reads and writes are usually unidirectional. Channels can be read and written asynchronously. The data in the channel is always read to a Buffer first, or always written from a Buffer.

Buffer: used to interact with NIO channels. As you know, data is read from the channel into the buffer, and written from the buffer to the channel. A buffer is essentially a block of memory to which data can be written and then read from it. This piece of memory is wrapped as a NIO Buffer object and provides a set of methods for easy access to this piece of memory. The interaction between channel and buffer is as follows:

Selector: Selector is a NIO channel that can detect one or more NIO channels in Java NIO. The channel registers the events of interest to the selector, and the selector can know whether the channel is ready for these events such as read and write events. In this way, a single thread can manage multiple channels and thus multiple network connections.

2. What is Java BIO?

In the synchronous blocking IO mode, the reading and writing of data must be blocked in a thread waiting for its completion. The classic example of boiling water is used here. Suppose there is a boiling water scene. There is a row of kettles boiling water. The working mode of BIO is to ask a thread to stay in a kettle until the kettle is boiled before proceeding to the next one. kettle. But actually the thread does nothing while waiting for the kettle to boil. I don't know when there is data to read in the io operation, so it has always been a blocking mode.

3. Differences and applications

Main difference:

Comparison of the differences between the two modes:

首先,线程是较为重量级的资源。bio当并发量大,而后端服务或客户端处理数据慢时就会产生产生大量线程处于等待中,即上述的阻塞,是非常严重的资源浪费。

此外,线程的切换也会导致cpu资源的浪费,单机内存限制也无法过多的线程,只能单向以流的形式读取数据。

nio使用单线程或者只使用少量的多线程,多个连接共用一个线程,消耗的线程资源会大幅减小。并且当处于等待(没有事件)的时候线程资源可以释放出来处理别的请求,通过事件驱动模型当有accept/read/write等事件发生后通知(唤醒)主线程分配资源来处理相关事件。以buffer缓冲区的形式处理数据,处理更为方便。

nio server demo:

Selector selector = Selector.open();  
ServerSocketChannel ssc = ServerSocketChannel.open();  
ssc.configureBlocking(false);  
ssc.socket().bind(new InetSocketAddress(port));  
  
ssc.register(selector, SelectionKey.OP_ACCEPT);  
  
while (true) {  
  
    // select()阻塞,等待有事件发生唤醒  
    int selected = selector.select();  
  
    if (selected > 0) {  
        Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();  
        while (selectedKeys.hasNext()) {  
            SelectionKey key = selectedKeys.next();  
            if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {  
              SocketChannel client = ((ServerSocketChannel) key.channel()).accept();
                // 处理 accept 事件  
                //注册read事件
                client.configureBlocking(false);
                client.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufSize));

            } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {  
                // 处理 read 事件  
               //注册write事件
            } else if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {  
                // 处理 write 事件  
            }  
            selectedKeys.remove();  
        }  
    }  
} 
复制代码

bio server demo:

 ServerSocket serverSocket;
        try {
            serverSocket = new ServerSocket(8000);
            while (true){
                Socket socket = serverSocket.accept();
                new Thread(()->{
                    try (InputStream inputStream = socket.getInputStream(); OutputStream outputStream =  socket.getOutputStream()) {

                        byte[] bytes =new byte[1024];
                        while (inputStream.read(bytes) != -1){
                            outputStream.write(bytes);
                            bytes = new byte[1024];
                        }

                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }).start();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
复制代码

4、Java学习视频

Java基础:

Java300集,Java必备优质视频_手把手图解学习Java,让学习成为一种享受

Java项目:

【Java游戏项目】1小时教你用Java语言做经典扫雷游戏_手把手教你开发游戏

【Java毕业设计】OA办公系统项目实战_OA员工管理系统项目_java开发

Guess you like

Origin juejin.im/post/7080089606711935013
Recommended