Java进阶之高并发核心Selector详解

Java进阶之高并发核心Selector详解

什么是Selector

Selector 是 Java NIO 中的一部分,它是一个可以通过单个线程处理多个 Channel 的组件。

在传统的 IO 模型中,每个连接都需要独立的线程进行处理,而使用 Selector 后,可以使用一个线程来处理多个连接,从而提高了程序的并发处理能力。

Selector 的使用

以下是 Selector 的基本使用过程:
1. 打开一个 Selector。
2. 将 Channel 注册到 Selector 中,并指定需要监听的事件类型。
3. 不断地轮询 Selector,当其中注册的 Channel 发生需要监听的事件时,Selector 返回对应的 SelectionKey,通过 SelectionKey 可以获取到需要处理的 Channel,进而进行业务逻辑处理。

示例1:使用 Selector 实现 TCP 服务器

下面是一个使用 Selector 实现 TCP 服务器的简单示例,其中使用到了 ServerSocketChannel 和 SocketChannel,具体代码如下:

public static void main(String[] args) throws IOException {
    // 创建 Selector
    Selector selector = Selector.open();

    // 创建 ServerSocketChannel
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    serverSocketChannel.configureBlocking(false);
    serverSocketChannel.bind(new InetSocketAddress(8080));
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

    // 轮询 Selector
    while (true) {
        if (selector.select() > 0) {
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            for (SelectionKey selectionKey : selectionKeys) {
                if (selectionKey.isAcceptable()) {
                    ServerSocketChannel serverChannel = (ServerSocketChannel) selectionKey.channel();
                    SocketChannel socketChannel = serverChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (selectionKey.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    ByteBuffer buf = ByteBuffer.allocate(1024);
                    int len = socketChannel.read(buf);
                    if (len > 0) {
                        buf.flip();
                        byte[] bytes = new byte[buf.remaining()];
                        buf.get(bytes);
                        String receivedMsg = new String(bytes);
                        System.out.println("received message: " + receivedMsg);
                    }
                }
                selectionKeys.remove(selectionKey);
            }
        }
    }
}

该代码段可以实现一个简单的 TCP 服务器,其中通过 ServerSocketChannel 和 SocketChannel 分别实现服务器端和客户端的连接与通信,并使用 Selector 实现了多连接的并发处理。

示例2:使用 Selector 实现 UDP 服务器

下面是一个使用 Selector 实现 UDP 服务器的示例,具体代码如下:

public static void main(String[] args) throws IOException {
    // 创建 Selector
    Selector selector = Selector.open();

    // 创建 DatagramChannel
    DatagramChannel datagramChannel = DatagramChannel.open();
    datagramChannel.configureBlocking(false);
    datagramChannel.bind(new InetSocketAddress(8080));
    datagramChannel.register(selector, SelectionKey.OP_READ);

    // 轮询 Selector
    while (true) {
        if (selector.select() > 0) {
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            for (SelectionKey selectionKey : selectionKeys) {
                if (selectionKey.isReadable()) {
                    DatagramChannel channel = (DatagramChannel) selectionKey.channel();
                    ByteBuffer buf = ByteBuffer.allocate(1024);
                    buf.clear();
                    channel.receive(buf);
                    buf.flip();
                    byte[] bytes = new byte[buf.remaining()];
                    buf.get(bytes);
                    String receivedMsg = new String(bytes);
                    System.out.println("received message: " + receivedMsg);

                    // 回复客户端
                    channel.send(ByteBuffer.wrap(("hello, " + receivedMsg).getBytes()), new InetSocketAddress("localhost", 8081));
                }
                selectionKeys.remove(selectionKey);
            }
        }
    }
}

该代码段可以实现一个简单的 UDP 服务器,通过 DatagramChannel 完成服务器的启动和数据收发,并使用 Selector 实现了多连接并发处理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java进阶之高并发核心Selector详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java并发编程示例(六):等待线程执行终止

    这里是关于“Java并发编程示例(六):等待线程执行终止”的完整攻略。 标题 Java并发编程示例(六):等待线程执行终止 简介 在Java并发编程中,常常需要等待一个线程或多个线程的执行终止,才能接着执行下一步的操作。这篇文章将介绍如何等待线程执行终止的几种方法,以及使用这些方法的示例。 阻塞等待线程执行终止的方法 使用Thread.join()方法 在主…

    多线程 2023年5月16日
    00
  • 详解进程同步与互斥机制

    详解进程同步与互斥机制 什么是进程同步和互斥? 在多进程环境下,多个进程之间共享计算机资源,例如共享内存区域。有时多个进程需要访问同一资源,这时候需要协调它们之间的访问,以免数据出现混乱。 进程同步是指协调多个进程之间的活动以达到一致的状态。进程互斥是指规范多个进程在不同时间访问资源的竞争环境,以防止它们同时访问同一资源而导致不可预测的后果。 进程同步的方法…

    多线程 2023年5月17日
    00
  • 浅谈Java并发中ReentrantLock锁应该怎么用

    当我们需要在并发环境下保证数据的正确性时,可以使用Java中的锁来达到目的。其中ReentrantLock是一种可重入锁,也就是说,它可以被同一个线程重复获取,防止了死锁的发生。但是,ReentrantLock的正确使用也需要一些细节上的注意,下面详细讲解一下ReentrantLock在Java并发编程中的应用。 一、ReentrantLock的常规使用方法…

    多线程 2023年5月17日
    00
  • linux并发连接50万的配置方法

    首先,要实现Linux系统并发连接50万的配置,需要考虑以下几个方面: 网络优化 调整TCP的参数,包括window size、backlog、max_tw_buckets等,其中window size模拟并发连接很重要。 增加网卡数量,选择高速网卡,如万兆以太网卡,可以提高网络带宽及IO能力。 使用高效的协议栈,如Google的BBR协议。 资源优化 内核…

    多线程 2023年5月16日
    00
  • iOS开发探索多线程GCD队列示例详解

    iOS开发探索多线程GCD队列示例详解 在iOS开发中,经常需要使用多线程编程来提高应用程序的性能和响应速度。而GCD(Grand Central Dispatch)则是iOS中多线程编程的一种新方式,它使用了轻量级的线程和任务调度机制,可以自动利用所有可用的CPU核心,方便易用且性能强大。 本文将针对GCD的队列进行详细讲解,包括串行队列和并发队列,并给出…

    多线程 2023年5月16日
    00
  • 并发编程之Java内存模型锁的内存语义

    让我来详细为您讲解Java内存模型的锁的内存语义。 Java内存模型简介 在Java语言中,多线程并发执行时会涉及到线程间共享变量的访问和修改,这就需要保证共享变量的正确性。而Java内存模型就是在多线程环境中用于保证共享变量内存可见性和有序性的一种抽象。Java内存模型通过规定线程间的通信方式和内存可见性协议来实现。 锁的内存语义 Java中的锁机制用于保…

    多线程 2023年5月17日
    00
  • java并发学习-CountDownLatch实现原理全面讲解

    Java并发学习-CountDownLatch实现原理全面讲解 在Java的并发编程中,有一个常见的工具类叫做CountDownLatch,用于等待一组线程完成它们的工作。本文将对CountDownLatch的原理进行全面讲解,包括它的实现原理、应用场景以及示例代码。 1. CountDownLatch的实现原理 CountDownLatch的实现原理非常简…

    多线程 2023年5月17日
    00
  • JAVA多线程和并发基础面试问答(翻译)

    为了实现该攻略,首先我们需要明确一些关键点,如何理解多线程和并发,以及一些常见的面试问题和答案。 理解多线程和并发 在理解多线程和并发之前,先需要知道进程和线程的概念。 进程 在计算机科学中,进程是一个电脑程序运行时的实例。一个程序至少有一个进程。在操作系统中,进程是资源分配和调度的一个单位,每个进程都有其专用的地址空间、代码段、数据段和系统栈。 线程 线程…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部