Maison  >  Article  >  Java  >  Comment implémenter le modèle IO et le sélecteur de technologie sous-jacente Java

Comment implémenter le modèle IO et le sélecteur de technologie sous-jacente Java

WBOY
WBOYoriginal
2023-11-08 18:00:181168parcourir

Comment implémenter le modèle IO et le sélecteur de technologie sous-jacente Java

Implémentation du modèle IO et du sélecteur de technologie sous-jacente Java

Dans la programmation Java, le modèle IO (Entrée-Sortie) et le sélecteur sont des technologies sous-jacentes très importantes. Ils sont cruciaux pour traiter efficacement les communications réseau et les opérations sur les fichiers. Dans cet article, nous approfondirons les principes d'implémentation du modèle IO et du sélecteur en Java, et fournirons des exemples de code spécifiques pour aider les lecteurs à mieux comprendre ces concepts.

1. Modèle IO

  1. Blocage IO
    Le modèle IO bloquant est le modèle IO le plus basique. Dans ce modèle, lorsqu'une application initie une demande d'E/S, si les données ne sont pas prêtes, l'application sera bloquée jusqu'à ce que les données soient prêtes à poursuivre l'exécution. La mise en œuvre de ce modèle est très simple, mais elle est moins efficace dans les environnements à forte concurrence.
  2. IO non bloquant
    Le modèle IO non bloquant vérifie l'état de préparation des opérations IO via une interrogation Si les données ne sont pas prêtes, l'application peut revenir immédiatement sans être bloquée. Cependant, ce modèle nécessite que l'application interroge en permanence et n'est pas efficace.
  3. IO multiplexées
    Le modèle IO multiplexé informe l'application de l'état de préparation aux opérations IO via une notification d'événement et ne nécessite pas que l'application interroge activement. Selector et SelectableChannel en Java sont basés sur le modèle IO multiplexé.

2. Utilisation de Selector

Selector est un composant important de la bibliothèque Java NIO Grâce à Selector, un seul thread peut gérer les opérations d'E/S de plusieurs canaux. Selector fournit un mécanisme de multiplexage d'E/S efficace qui peut considérablement améliorer l'efficacité de la communication réseau.

Les étapes de base pour utiliser Selector sont les suivantes :

  1. Create Selector
    Selector selector = Selector.open();
  2. Create SelectableChannel
    SelectableChannel channel = new SocketChannel();
  3. Enregistrez le canal sur Selector
    channel. register( selector, SelectionKey.OP_READ);
  4. Sélectionner les événements IO via Selector
    int readyChannels = selector.select();
  5. Gérer les événements IO
    Set selectedKeys = selector.selectedKeys();
    Iterator = selectedKeys .iterator();
    while (keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();
    if (key.isReadable()) {
    // Gérer les événements lisibles
    }
    keyIterator.remove( ) ;
    }

Grâce aux étapes ci-dessus, nous pouvons voir que lors de l'utilisation du sélecteur, nous devons d'abord créer l'objet, puis enregistrer le canal pour les opérations IO dans le sélecteur, puis sélectionner et traiter les événements IO.

Jetons un coup d'œil à un exemple spécifique pour implémenter un programme simple de communication serveur et client basé sur un sélecteur.

Exemple de code côté serveur :

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();
      }
    }
  }
}

Exemple de code côté client :

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();
      }
    }
  }
}

Grâce à l'exemple de code ci-dessus, nous pouvons voir comment utiliser Selector pour communiquer entre le serveur et le client. Dans le serveur, nous créons d'abord un ServerSocketChannel et l'enregistrons sur le sélecteur, puis sélectionnons les événements IO dans la boucle et gérons la demande de connexion et la lecture des données du client ; dans le client, nous créons un SocketChannel et l'enregistrons sur le sélecteur, puis dans la boucle, sélectionnez les événements IO et gérez les connexions et l'envoi de données.

Résumé

Grâce à l'introduction et à l'exemple de code de cet article, j'espère que les lecteurs pourront mieux comprendre les principes de mise en œuvre et l'utilisation du modèle IO et du sélecteur en Java. Une étude approfondie et la maîtrise de ces technologies sous-jacentes sont essentielles à l’écriture de programmes efficaces de communication réseau et d’exploitation de fichiers. Il convient de noter que dans le développement réel, les modèles et technologies IO appropriés doivent être sélectionnés en fonction de besoins et de scénarios spécifiques afin de mieux répondre aux exigences du projet.

Au cours du processus d'apprentissage, les lecteurs peuvent également approfondir leur compréhension et leur maîtrise de ces technologies sous-jacentes en lisant des documents plus pertinents et en se référant à des cas d'application plus pratiques. Dans le même temps, une pratique et une expérimentation continues aideront les lecteurs à comprendre ces concepts plus en profondeur et à être capables de les appliquer habilement au développement de projets réels.

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