SoFunction
Updated on 2025-04-06

One article will help you understand how Java implements high concurrency programming in network NIO

Introduction to Java NIO and high concurrency network programming implementation

Java NIO

NIO (Non-blocking I/O, non-blocking I/O) is a new set of I/O APIs introduced by Java in JDK 1.4, aiming to solve the problem of insufficient performance and scalability of traditional I/O (i.e. BIO, blocking I/O) in high concurrency scenarios.

Core features of NIO

Non-blocking I/O: Supports non-blocking mode, allowing threads to avoid waiting for I/O operations to complete, thereby improving system resource utilization.

Buffer: Reading and writing data through buffers, not directly through streams.

Selector: manages multiple channels through one thread, greatly improving the scalability and efficiency in high concurrency scenarios.

Multiplexing: The status of multiple channels can be monitored simultaneously through the Selector mechanism (such as connection ready, data readiness, etc.).

Comparison of BIO (blocking I/O) vs. NIO (non-blocking I/O)

characteristic BIO NIO
I/O mode Blocking, the thread will wait for the I/O to complete Non-blocking, threads do not need to wait for I/O to complete
Threading model One thread per connection One thread manages multiple connections
Applicable scenarios Low concurrency, simple scenarios High concurrency, network programming scenarios
performance High thread resource cost and poor scalability More efficient resource utilization and better scalability

Core components of NIO

(aisle)

Similar to Stream, but Channel supports both read and write.

Common Channels: SocketChannel, ServerSocketChannel, DatagramChannel, FileChannel.

(Buffer)

Data reading and writing are performed through a Buffer.

Common buffers: ByteBuffer, CharBuffer, IntBuffer, etc.

(Selector)

Core component used to listen for events in multiple channels, such as connection ready, read ready, write ready, etc.

Through multiplexing mechanism, one thread manages multiple channels.

Represents the registration relationship between the channel and the selector, including the event type of the channel (such as read, write, connect, etc.).

Java NIO Network High Concurrency Programming Example

Scene description

Server side: Listen to client requests, receive data and return information.

Client: Connect to the server, send data and receive responses.

Server-side code

import ;
import ;
import ;
import ;
import .*;
import ;

public class NioServer {
    public static void main(String[] args) {
        try {
            // 1. Create ServerSocketChannel for listening to client connections            ServerSocketChannel serverChannel = ();
            (new InetSocketAddress(8080));
            (false); // Set to non-blocking mode
            // 2. Create Selector and register ServerSocketChannel to listen for ACCEPT events            Selector selector = ();
            (selector, SelectionKey.OP_ACCEPT);

            ("NIO Server started on port 8080...");

            while (true) {
                // 3. Check whether any event occurs, block and wait                if (() == 0) {
                    continue; // If no event is ready, continue the loop                }

                // 4. Get ready event collection                Iterator<SelectionKey> keyIterator = ().iterator();
                while (()) {
                    SelectionKey key = ();
                    (); // Remove the key currently processed to avoid repeated processing
                    try {
                        // 5. Handle different events                        if (()) { // Client connection event                            handleAccept(key, selector);
                        } else if (()) { // Read client data events                            handleRead(key);
                        }
                    } catch (IOException e) {
                        ("Error handling client connection: " + ());
                        (); // Cancel the error key                        if (() != null) {
                            ().close();
                        }
                    }
                }
            }
        } catch (IOException e) {
            ();
        }
    }

    // Handle ACCEPT events    private static void handleAccept(SelectionKey key, Selector selector) throws IOException {
        ServerSocketChannel serverChannel = (ServerSocketChannel) ();
        SocketChannel clientChannel = (); // Accept client connections        (false); // Set to non-blocking mode        (selector, SelectionKey.OP_READ); // Register READ Events        ("Client connected: " + ());
    }

    // Handle READ events    private static void handleRead(SelectionKey key) throws IOException {
        SocketChannel clientChannel = (SocketChannel) ();
        ByteBuffer buffer = (1024);
        int bytesRead;

        try {
            bytesRead = (buffer); // Read data from the channel        } catch (SocketException e) {
            ("Connection reset by client: " + ());
            ();
            ();
            return;
        }

        if (bytesRead > 0) {
            (); // Switch to read mode            String message = new String((), 0, ());
            ("Received from client: " + message);

            // Write back data to the client            ();
            (("Echo: " + message).getBytes());
            ();
            (buffer);
        } else if (bytesRead == -1) { // Client disconnect            ("Client disconnected: " + ());
            ();
            (); // Unregistered event        }
    }
}

Client Code

import ;
import ;
import ;
import ;

public class NioClient {

    public static void main(String[] args) throws IOException {
        // 1. Create SocketChannel Connection Server        SocketChannel socketChannel = ();
        (false);

        if (!(new InetSocketAddress("127.0.0.1", 8080))) {
            // Wait for the connection to complete            while (!()) {
                ("Connecting to server...");
            }
        }

        ("Connected to the server");

        // 2. Send data to the server        String message = "Hello, NIO Server!";
        ByteBuffer buffer = (());
        (buffer);

        // 3. Receive data written back by the server        ();
        int bytesRead = (buffer);
        if (bytesRead > 0) {
            ();
            String response = new String((), 0, ());
            ("Received from server: " + response);
        }

        ();
    }
}

Running results

Client output

 Connected to the server
 Received from server: Echo: Hello, NIO S
The process has ended, the exit code is 0

Server-side output

 NIO Server started on port 8080...
 Client connected: /127.0.0.1:50104
 Received from client: Hello, NIO Server!
 Connection reset by client: /127.0.0.1:50104

Key points of high concurrency in NIO

Non-blocking I/O: Selector can listen to multiple client connections at the same time, eliminating the need to create a thread for each connection, reducing thread overhead.

Multiplexing: Selector provides a multiplexing mechanism that can listen to multiple events at the same time (such as connection ready, read ready, etc.).

IO operation optimization: I/O operation is performed through ByteBuffer, which avoids frequent data copying of traditional streams and improves read and write efficiency.

Limitations and improvements of NIO

1. Limitations

The use of NIO is relatively complex and requires manual management of channels and buffers.

In high concurrency scenarios, the performance of Selector may become a bottleneck.

2. Direction of improvement

Netty: A high-performance networking framework based on NIO simplifies the use of NIO while providing higher throughput and scalability.

Asynchronous I/O (AIO): Java NIO 2.0 (introduced in JDK 7) provides asynchronous I/O, further optimizing thread resource utilization.

Applicable scenarios and suggestions

Applicable scenarios: highly concurrent network applications, such as web servers, message push services; I/O-intensive applications.

Recommended usage: For complex high-performance network applications, it is recommended to use mature frameworks such as Netty to avoid directly manipulating the underlying code of NIO.

The above is a detailed article that will help you understand how Java can implement high concurrency programming in network NIO. For more information about Java network NIO, please pay attention to my other related articles!