zoukankan      html  css  js  c++  java
  • Redis单线程模型

    1、单线程模型概述

    Redis 使用单线程模型来处理各种 socket 事件,所以说 Redis 是单线程的,使用单线程轮训所有 socket 连接,监听所有 socket 发送过的命令,然后对齐进行响应,如果其中一个 socket 的命令执行时间过长,则会导致后续的客户端命令产生堵塞。

    2、为什么采用单线程模型还这么快?

    • 纯内存操作。
    • 单线程可以避免上下文切换,不用考虑锁的问题。
    • 使用 IO多路复用模型,非堵塞IO。多路是指多个网络连接,复用是指使用一个线程进行处理。

    3、单线程模型代码

    public class NIOServer implements Runnable {
     
        private final Selector selector = Selector.open();
        private final ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
     
        public NIOServer() throws IOException {
            serverSocketChannel.socket().bind(new InetSocketAddress(9999));
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        }
     
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                try {
                    if (selector.select() <= 0) {
                        continue;
                    }
     
                    Set<SelectionKey> selectionKeys = selector.selectedKeys();
                    Iterator<SelectionKey> iterator = selectionKeys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey selectionKey = iterator.next();
     
                        // 分发事件
                        dispatchEvent(selectionKey);
     
                        iterator.remove();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
     
        /**
         * 分发事件处理
         */
        private void dispatchEvent(SelectionKey selectionKey) throws IOException {
            if (selectionKey.isAcceptable()) {
                // 新连接注册
                SocketChannel socketChannel = serverSocketChannel.accept();
                socketChannel.configureBlocking(false);
                socketChannel.register(selector, SelectionKey.OP_READ);
            } else if (selectionKey.isReadable()) {
                // 可读
            } else if (selectionKey.isWritable()) {
                // 可写
            }
        }
    } 
    ------------------------------我是博客签名------------------------------
    座右铭:不要因为知识简单就忽略,不积跬步无以至千里。
    版权声明:自由转载-非商用-非衍生-保持署名。
    本作品采用知识共享署名 4.0 国际许可协议进行许可。
    ----------------------------------------------------------------------
  • 相关阅读:
    安装node和npm
    安装git
    常用软件
    vscode常用插件
    git生成ssh key
    04.接口初始化规则与类加载器准备阶段和初始化阶段的意义
    03.编译期常量与运行期常量的区别与数组创建本质分析
    02.常量的本质含义与反编译及助记符
    01.类加载,连接与初始化过程
    HTTP 状态码大全
  • 原文地址:https://www.cnblogs.com/wuqinglong/p/14670687.html
Copyright © 2011-2022 走看看