Maison  >  Article  >  Java  >  Comment la technologie NIO gère-t-elle les opérations d'E/S non bloquantes dans les fonctions Java ?

Comment la technologie NIO gère-t-elle les opérations d'E/S non bloquantes dans les fonctions Java ?

王林
王林original
2024-05-01 10:12:02517parcourir

La technologie NIO gère les opérations d'E/S non bloquantes et utilise des mécanismes basés sur les événements pour traiter les E/S de manière asynchrone afin d'améliorer l'efficacité dans les scénarios de requêtes simultanées élevées. Gérez les opérations d'E/S en définissant les canaux, en créant des sélecteurs, en enregistrant les canaux auprès des sélecteurs, en écoutant les événements et en gérant les étapes des événements. Le cas pratique montre un programme Echo non bloquant côté serveur qui utilise NIO pour accepter et répondre de manière asynchrone aux demandes de connexion client.

Java 函数中 NIO 技术如何处理非阻塞 IO 操作?

La technologie NIO dans les fonctions Java gère les opérations d'E/S non bloquantes

NIO (E/S non bloquantes) est un moyen efficace de gérer des requêtes simultanées élevées dans les grandes applications réseau, il utilise le mode non bloquant via des événements. mécanisme pour gérer les E/S de manière asynchrone. L'API NIO est fournie en Java pour décrire les événements, les canaux et les tampons NIO.

1. Définir le canal NIO

Un canal dans NIO représente un fichier ouvert ou une connexion réseau. Il existe quatre principaux types de canaux :

import java.nio.channels.*;

// 文件通道
FileChannel fileChannel = FileChannel.open(Paths.get("file.txt"), StandardOpenOption.READ);

// 套接字通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

// 套接字通道
SocketChannel socketChannel = SocketChannel.open();

// 套接字通道
DatagramChannel datagramChannel = DatagramChannel.open();

2. Créer des sélecteurs

Les sélecteurs sont utilisés pour surveiller les événements sur plusieurs canaux. Ils peuvent gérer simultanément un grand nombre de connexions provenant de différents canaux, gérant ainsi efficacement les opérations d’E/S.

import java.nio.channels.Selector;

Selector selector = Selector.open();

3. Enregistrez la chaîne

Enregistrez la chaîne dans le sélecteur pour surveiller les événements qui vous intéressent, tels que les opérations de lecture/écriture.

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

4. Écoute des événements

Utilisez la méthode select() pour surveiller les événements dans le sélecteur jusqu'à ce qu'un événement se produise. Cette méthode se bloque jusqu'à ce qu'au moins un canal soit prêt à être traité. select() 方法监视 Selector 中的事件,直到有事件发生。该方法会阻塞,直到至少有一个通道准备好处理。

int numKeys = selector.select();

5. 处理事件

通过检查 SelectionKey

for (SelectionKey key : selector.selectedKeys()) {
    if (key.isAcceptable()) {
        // 监听新的连接请求
    } else if (key.isReadable()) {
        // 读取数据
    } else if (key.isWritable()) {
        // 写入数据
    }
}

5. Gestion des événements

Gérez les événements qui se produisent en cochant SelectionKey, qui fournit des détails sur le canal et le type sur lequel l'événement s'est produit.

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class NonBlockingEchoServer {

    public static void main(String[] args) throws IOException {
        // 创建一个 ServerSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8080));
        serverSocketChannel.configureBlocking(false);

        // 创建一个 Selector
        Selector selector = Selector.open();

        // 注册 ServerSocketChannel 到 Selector,监视 ACCEPT 事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            // 监听事件
            selector.select();

            // 获取选择的 SelectionKey 集合
            Set<SelectionKey> selectedKeys = selector.selectedKeys();

            // 遍历选择的 SelectionKey
            Iterator<SelectionKey> iterator = selectedKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();

                if (key.isAcceptable()) {
                    // 新的连接请求
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    // 读取数据
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int readBytes = socketChannel.read(buffer);
                    if (readBytes > 0) {
                        // 响应客户端消息
                        buffer.flip();
                        socketChannel.write(buffer);
                    }
                }

                // 从集合中删除处理过的 SelectionKey
                iterator.remove();
            }
        }
    }
}

🎜Cas pratique : programme Echo non bloquant côté serveur🎜🎜🎜Cet exemple crée un serveur qui utilise NIO pour accepter et répondre de manière asynchrone aux connexions client. 🎜rrreee

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn