• 验证NIO的非阻塞模型


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

    1. import java.net.InetSocketAddress;
    2. import java.nio.ByteBuffer;
    3. import java.nio.channels.ServerSocketChannel;
    4. import java.nio.channels.SocketChannel;
    5. import java.util.LinkedList;
    6. import java.util.List;
    7. import java.util.concurrent.TimeUnit;
    8. public class NioServer {
    9. public static void main(String[] args) throws Exception {
    10. ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    11. //服务端非阻塞
    12. serverSocketChannel.configureBlocking(false);
    13. serverSocketChannel.bind(new InetSocketAddress(8888));
    14. List clients = new LinkedList<>();
    15. while (true) {
    16. TimeUnit.SECONDS.sleep(1);
    17. SocketChannel client = serverSocketChannel.accept();
    18. if (null == client) {
    19. System.err.println("没有新的客户端连接.....");
    20. } else {
    21. //客户端非阻塞
    22. client.configureBlocking(false);
    23. System.err.println(client.socket());
    24. clients.add(client);
    25. }
    26. ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
    27. for (SocketChannel socketChannel : clients) {
    28. int num = socketChannel.read(byteBuffer);
    29. if (num > 0) {
    30. byteBuffer.flip();
    31. byte[] bytes = new byte[byteBuffer.limit()];
    32. byteBuffer.get(bytes);
    33. String b = new String(bytes);
    34. System.err.println(b);
    35. byteBuffer.clear();
    36. }
    37. }
    38. }
    39. }
    40. }
    //服务端非阻塞
    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

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

  • 相关阅读:
    6.0、C语言数据结构——链式存储结构 (1)
    如何利用 RPA 实现自动化获客?
    「重启程序」的正面和反面
    gulp自动化构建
    带你读论文丨Fuzzing漏洞挖掘详细总结 GreyOne
    读书笔记_小米创业思考
    【iOS开发】-通知传值
    AndroidManifest.xml 添加 android:supportsRtl=“true“报错误
    PHP:namespace 关键字和 __NAMESPACE__ 常量
    【数据结构-查找】散列表
  • 原文地址:https://blog.csdn.net/qq_17805707/article/details/133384859