资讯专栏INFORMATION COLUMN

Java NIO 入门

liaorio / 1935人阅读

摘要:关于多路复用很多人用过和接口,用来操作文件等等操作。熟悉操作系统的人会知道,操作非阻塞无非几种多路复用这里的复用模型有几个是操作系统相关的也就是说,并不是所有的操作系统都可以用,典型的就是是的专利,是的专利比如。

关于多路复用

很多人用过InputStreamOutputStream接口,用来操作文件Socket等等 IO 操作。
如果是简单的,速度较快的 IO 操作,我们用Stream类的接口,依然可以风生水起。
如果你要使用非阻塞的 IO 的话,他们可能就满足不了你了。

熟悉操作系统的人会知道,操作非阻塞 IO 无非几种多路复用:

select

poll

epoll

kqueue

IOCP

这里的复用模型有几个是操作系统相关的——也就是说,并不是所有的操作系统都可以用,典型的就是IOCPWindows的"专利",kqueueBSD的"专利"(比如macOS)。

那么 java 作为一门跨平台的语言解决方案,是如何在虚拟机上使用 non-blocking IO 的呢?
具体的实现我们可以不管,它使用了Selector的 API,调用方式非常类似select

Channel & ByteBuffer vs Stream

nio中,不再使用Stream APISocket进行交互,而是使用ChannelByteBuffer进行交互,
Channel负责管道的工作,ByteBuffer负责缓存的工作。

原先InputStreamOutputStream的工作就由Channel做掉了,如果这个Channel支持Select模型的话,它就是SelectableChannel的子类。
那么,在消息循环的模型中,首先要建立循环,像我们的Looper.loop()一样,我们先用Selector.open()新建一个Selector

Selector eventSelector = Selector.open();

// 设置这个 channel 是非阻塞的
socketChannel.configureBlocking(false);

// 注册到 selector 里,并设置好关心的事件
socketSelectionKey = socketChannel.register(eventSelector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
Selector

接下来调用 eventSelector.select() 阻塞,就能在你关心的事件到来的时候,阻塞就会被唤醒,处理事件。

sample:

while (connected) {
    eventSelector.select();
    Set keys = eventSelector.selectedKeys();
    Iterator iterator = keys.iterator();
    while (iterator.hasNext()) {
        SelectionKey key = iterator.next();
        if (key.isReadable()) {
            // 当 socket 可读
            internalOnRead((ReadableByteChannel) key.channel());
        }

        if (key.isWritable()) {
            // 当 socket 可写
            internalOnWrite((WritableByteChannel) key.channel());
        }
        iterator.remove();
    }
}
总结

nio 对于客户端的优势几乎没有,但是可以让代码更好管理; 如果这时候你使用的是ServerSocket,好处就立马体现了,因为你的业务需求很可能是这样:

master 线程,开启 accept.

如果有客户接入,开启一个 worker,用来服务 client。

服务完后,保持或者关闭这个连接。

(这个业务模型类似Apache httpd)这样的业务模型可能导致过多的线程开销,使得并发量并不高。

那么,老生常谈的event-driven的模型在java中,就差不多是这样的逻辑:

master 线程,开启 selector, 并为 ServerSocket 注册 accept, read, write 等事件。

客户接入,为 client socket 注册 read, write 事件,依旧在该线程里面进行循环。

当 event trigger 的时候,处理相关业务逻辑。

第二个模型只启动了一个线程,所有的IO操作都在 OS 里面完成了,用户空间内的资源消耗大大降低,这也是我们把 Server 端的 IO 改成 nio 的优势。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66687.html

相关文章

  • 少啰嗦!一分钟带你读懂JavaNIO和经典IO的区别

    摘要:的选择器允许单个线程监视多个输入通道。一旦执行的线程已经超过读取代码中的某个数据片段,该线程就不会在数据中向后移动通常不会。 1、引言 很多初涉网络编程的程序员,在研究Java NIO(即异步IO)和经典IO(也就是常说的阻塞式IO)的API时,很快就会发现一个问题:我什么时候应该使用经典IO,什么时候应该使用NIO? 在本文中,将尝试用简明扼要的文字,阐明Java NIO和经典IO之...

    Meils 评论0 收藏0
  • 慕课网_《Netty入门之WebSocket初体验》学习总结

    时间:2018年04月11日星期三 说明:本文部分内容均来自慕课网。@慕课网:https://www.imooc.com 教学源码:https://github.com/zccodere/s... 学习源码:https://github.com/zccodere/s... 第一章:课程介绍 1-1 课程介绍 什么是Netty 高性能、事件驱动、异步非阻塞的IO Java开源框架 基于NIO的客户...

    Noodles 评论0 收藏0
  • 【源码阅读】Java-NIO之Selector创建过程详解

    摘要:好了,目前还不难,我们起码知道这个抽象类上面的部分关系,因此当然也有自己的方法,如下。又来一个的供应商好吧,大佬们总是喜欢用一些设计模式的东西,没错,也是一个抽象类,这个现在不用太在意了。 前言 java nio,一个入门netty之前需要了解下的非阻塞I/O实现,传统的Socket通信,启动监听后accept会一直处于阻塞状态,那么如果你想要多个(并发)通信时,那么我们就需要多个线性...

    187J3X1 评论0 收藏0
  • 高并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    supernavy 评论0 收藏0
  • 高并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    ddongjian0000 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<