4. Non-blocking network communication of NIO

  • Traditional IO streams are blocking. That is, when a thread calls read() or write(), the thread blocks until some data is read or written, and the thread cannot perform other tasks in the meantime. Therefore, when I/O operations are completed, the server must provide an independent thread for each client because the thread is blocked. When the server needs to process a large number of clients, the server performance deteriorates dramatically.

  • Java NIO is non-blocking. When a thread reads or writes data from a channel, it can perform other tasks if no data is available. Threads typically spend idle time of non-blocking IO performing IO operations on other channels, so a single thread can manage multiple input and output channels. Thus, NIO allows the server side to use one or a limited number of threads to simultaneously process all the clients connected to the server side

4.1 Selectors

  • A Selector is a multiplexer of a SelectableChannle object. A Selector can monitor the I/O status of multiple SelectableChannel at the same time. With Selector, a single thread can manage multiple channels. Selector is the heart of non-blocking IO.
  • SelectableChannle’s structure is shown below:

4.2 Application of selectors

1. Create a Selector: Create a Selector by calling Selector. Open ().

// Create a selector
Selector selecttor = Selector.open();
Copy the code

2. Registered channels with the Selector: SelectableChannel. Register (Selector sel, int ops);

// Create a Socket
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9898);

/ / get a SocketChannel
SocketChannel channel = socket.getChannel();

// Create a selector
channel.configureBlocking(false);

// Register a Channel with Selector
SelectionKey key = channel.register(seletor, SelectionKey.OP_READ);
Copy the code
  • When a channel is registered with a Selector by calling register(Selector sel, int OPS), the Selector listens for events on the channel, which need to be specified by the second parameter ops.

  • The types of events that can be listened on (represented by the four constants of the SelectionKey) :

    • Read: selectionkey.op_read (1)
    • Write: selectionkey.op_write (4)
    • Connection: selectionKey.op_connect (8)
    • Selectionkey.op_accept (16)
  • If you listen for more than one event when registering, you can use the bit-or operator to connect.

// Register "listening events"
int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE
Copy the code

4.3 SelectionKey

SelectionKey: Represents the registration relationship between a SelectableChannel and a Selector. An event (select key) is selected each time a channel is registered with the selector. The selection key contains two sets of operations represented as integer values. Each bit of the action set represents what the key’s channel supports

4.4 Common methods of Selector