验证NIO的非阻塞模型

我们知道传统BIO模型在等待客户端连接时是阻塞的,读取数据时如果没有数据,也是阻塞的,而NIO则可以配置成非阻塞,废话不多说,直接看代码:

复制代码
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class NioServer {
    public static void main(String[] args) throws Exception {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //服务端非阻塞
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8888));
        List<SocketChannel> clients = new LinkedList<>();
        while (true) {
            TimeUnit.SECONDS.sleep(1);
            SocketChannel client = serverSocketChannel.accept();
            if (null == client) {
                System.err.println("没有新的客户端连接.....");
            } else {
                //客户端非阻塞
                client.configureBlocking(false);
                System.err.println(client.socket());
                clients.add(client);
            }
            ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
            for (SocketChannel socketChannel : clients) {
                int num = socketChannel.read(byteBuffer);
                if (num > 0) {
                    byteBuffer.flip();
                    byte[] bytes = new byte[byteBuffer.limit()];
                    byteBuffer.get(bytes);
                    String b = new String(bytes);
                    System.err.println(b);
                    byteBuffer.clear();
                }
            }
        }
    }
}
复制代码
//服务端非阻塞
serverSocketChannel.configureBlocking(false);
//客户端非阻塞
client.configureBlocking(false);

这两行代码非常重要,serverSocketChannel.configureBlocking(false)这里设置的是true,那么只要没有客户端连接,SocketChannel client = serverSocketChannel.accept();这一行就会阻塞住,就不会每隔一秒打印没"有新的客户端连接....."

直到通过telnet连接一个客户端之后:

但是还是会继续阻塞等待下一个客户端连接,我们把serverSocketChannel.configureBlocking(false)这一行还原成false,client.configureBlocking(false);设置为true,再看效果:

第一个客户端连接上之后,一定要输入数据,不然read就会一直阻塞

我们再把两个选项都回复到false,然后丢到linux系统去运行,看看系统调用的情况(如何查看系统调用情况,之前有一篇BIO模型的文章Java当中的BIO模型-CSDN博客):

可以看到accept并不会像NIO一样阻塞,而是直接返回-1,write(2, "\346\262\241\346\234\211\346\226\260\347\232\204\345\256\242\346\210\267\347\253\257\350\277\236\346\216\245.....", 32) = 32

这一行其实就是输出"有新的客户端连接....."这句话

相关推荐
weixin_472339462 小时前
高效处理大体积Excel文件的Java技术方案解析
java·开发语言·excel
枯萎穿心攻击2 小时前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
Eiceblue4 小时前
【免费.NET方案】CSV到PDF与DataTable的快速转换
开发语言·pdf·c#·.net
m0_555762904 小时前
Matlab 频谱分析 (Spectral Analysis)
开发语言·matlab
浪裡遊5 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
lzb_kkk6 小时前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节
好开心啊没烦恼6 小时前
Python 数据分析:numpy,说人话,说说数组维度。听故事学知识点怎么这么容易?
开发语言·人工智能·python·数据挖掘·数据分析·numpy
简佐义的博客7 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang
程序员爱钓鱼7 小时前
【无标题】Go语言中的反射机制 — 元编程技巧与注意事项
开发语言·qt