Home  >  Article  >  Java  >  How to implement the IO model and Selector of Java underlying technology

How to implement the IO model and Selector of Java underlying technology

WBOY
WBOYOriginal
2023-11-08 18:00:181119browse

How to implement the IO model and Selector of Java underlying technology

Implementing the IO model and Selector of Java underlying technology

In Java programming, the IO (Input-Output) model and Selector are very important underlying technologies. They are very important for Handling network communications and file operations efficiently is critical. In this article, we will delve into the implementation principles of the IO model and Selector in Java, and provide specific code examples to help readers better understand these concepts.

1. IO model

  1. Blocking IO
    The blocking IO model is the most basic IO model. Under this model, when an application initiates an IO request, if the data is not ready, the application will be blocked until the data is ready to continue execution. The implementation of this model is very simple, but it is less efficient in high concurrency environments.
  2. Non-blocking IO
    The non-blocking IO model checks the readiness of IO operations through polling. If the data is not ready, the application can return immediately without being blocked. However, this model requires the application to continuously poll and is not efficient.
  3. Multiplexed IO
    The multiplexed IO model informs the application of the preparation status of the IO operation through event notification, and does not require the application to actively poll. Selector and SelectableChannel in Java are based on the multiplexed IO model.

2. Use of Selector

Selector is an important component in the Java NIO library. Through Selector, single-threaded management of multiple Channel IO operations can be achieved. Selector provides an efficient IO multiplexing mechanism that can greatly improve the efficiency of network communication.

The basic steps for using Selector are as follows:

  1. Create Selector
    Selector selector = Selector.open();
  2. Create SelectableChannel
    SelectableChannel channel = new SocketChannel();
  3. Register the channel to the Selector
    channel.register(selector, SelectionKey.OP_READ);
  4. Select IO events through the Selector
    int readyChannels = selector. select();
  5. Handling IO events
    Set selectedKeys = selector.selectedKeys();
    Iterator keyIterator = selectedKeys.iterator();
    while (keyIterator. hasNext()) {
    SelectionKey key = keyIterator.next();
    if (key.isReadable()) {
    // Handle readable events
    }
    keyIterator.remove() ;
    }

Through the above steps, we can see that when using the Selector, you need to create the object first, then register the channel for IO operations to the Selector, and then perform the IO event Selection and processing.

Let’s look at a specific example to implement a simple Selector-based server and client communication program.

Server code example:

public class Server {
  public static void main(String[] args) throws IOException {
    ServerSocketChannel serverSocket = ServerSocketChannel.open();
    serverSocket.socket().bind(new InetSocketAddress(8888));
    serverSocket.configureBlocking(false);

    Selector selector = Selector.open();
    serverSocket.register(selector, SelectionKey.OP_ACCEPT);

    while (true) {
      int readyChannels = selector.select();
      if (readyChannels == 0) continue;

      Set<SelectionKey> selectedKeys = selector.selectedKeys();
      Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
      while (keyIterator.hasNext()) {
        SelectionKey key = keyIterator.next();
        if (key.isAcceptable()) {
          SocketChannel client = serverSocket.accept();
          client.configureBlocking(false);
          client.register(selector, SelectionKey.OP_READ);
          System.out.println("客户端连接:" + client.getRemoteAddress());
        } else if (key.isReadable()) {
          SocketChannel client = (SocketChannel) key.channel();
          ByteBuffer buffer = ByteBuffer.allocate(1024);
          int bytesRead = client.read(buffer);
          while (bytesRead > 0) {
            buffer.flip();
            while (buffer.hasRemaining()) {
              System.out.print((char) buffer.get());
            }
            System.out.println();
            bytesRead = client.read(buffer);
          }
        }
        keyIterator.remove();
      }
    }
  }
}

Client code example:

public class Client {
  public static void main(String[] args) throws IOException {
    SocketChannel socket = SocketChannel.open();
    socket.configureBlocking(false);
    socket.connect(new InetSocketAddress("localhost", 8888));

    Selector selector = Selector.open();
    socket.register(selector, SelectionKey.OP_CONNECT);

    while (true) {
      int readyChannels = selector.select();
      if (readyChannels == 0) continue;

      Set<SelectionKey> selectedKeys = selector.selectedKeys();
      Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
      while (keyIterator.hasNext()) {
        SelectionKey key = keyIterator.next();
        if (key.isConnectable()) {
          if (socket.finishConnect()) {
            socket.register(selector, SelectionKey.OP_WRITE);
            System.out.println("客户端连接成功");
          }
        } else if (key.isWritable()) {
          ByteBuffer buffer = ByteBuffer.allocate(1024);
          buffer.put("Hello, Server".getBytes());
          buffer.flip();
          while (buffer.hasRemaining()) {
            socket.write(buffer);
          }
          System.out.println("发送数据到服务端");
        }
        keyIterator.remove();
      }
    }
  }
}

Through the above code example, we can see how to use Selector to communicate between the server and the client. In the server, we first create a ServerSocketChannel and register it on the Selector, then select IO events in the loop and handle the client's connection request and data reading; in the client, we create a SocketChannel and register it on the Selector, and then in the loop Select IO events and handle connections and data sending.

Summary

Through the introduction and sample code of this article, I hope readers can better understand the implementation principles and usage of the IO model and Selector in Java. In-depth study and mastery of these underlying technologies is crucial to writing efficient network communication and file operation programs. It should be noted that in actual development, appropriate IO models and technologies need to be selected according to specific needs and scenarios to better meet the requirements of the project.

In the process of learning, readers can also deepen their understanding and mastery of these underlying technologies by reading more relevant materials and referring to more practical application cases. At the same time, continuous practice and experimentation will help readers understand these concepts more deeply and be able to apply them skillfully to actual project development.

The above is the detailed content of How to implement the IO model and Selector of Java underlying technology. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn