netty技术内幕一(Selector,SelectionKey)

通过前面对duubo的介绍,我们支持,dubbo底层默认的使用netty作为nio框架来进行网络通信,等于说netty是基础,dubbo是建立在netty之上的能力扩展,所以后面我们会通过系列文章,对netty做一个系列化的介绍。只有通过对netty的完全的理解,我们才能完全的吃透dubbo,使用dubbo。
Selector是 SelectableChannel对象的多路复用器
可以使用Selector的 open 方法来创建一个Selector对象,open方法会使用系统默认的java.nio.channels.spi.SelectorProvider 对象来创建一个新的Selector对象。
也可以使用java.nio.channels.spi.SelectorProvider的openSelector方法来创建一个Selector对象。
一个Selector一直保持 open 状态,除非显示的调用其close 方法。
一个 selectable的channel注册到一个Selector之后会 返回一个 SelectionKey对象来表征这个关系。一个Selector维护这三组 selection keys。
其中 key set 存储的 keys 代表了所有注册到此Selector的当前的Channel。可以通过 keys() 方法返回此set

其中selected-key 集合中存储的keys代表在一个 selection操作期间,注册到此Selector上的某些Channel,这些Channel至少被Selector感知到了发生了其自注册的感兴趣事件。selected-key永远是key set的一个子集。

还有一组canneled-key ,这个集合不能被我们直接的获取,其存储了那些关联的Channel没有被deregistered 但是被cancelled的key。
当Selector被初创出来的时候,这三个集合都是空集合。

当通过调用SelectableChannel的register(Selector,int)方法时,一个key 会被加入到Selector的 key set 集合中。在发生 selection操作期间,被cancelled的key会被移除出key set。 Key set集合不能直接的被修改。

不管是关闭channel还是通过 SelectionKey的cancel方法都会将此channel关联的key加入到canneled-key 集合。取消一个key会导致在下个selection操作期间会将此关联的channel注销,并将此key在selector关联的所有的 key set集合里面移除(等于说取消是有延迟的)

在selection操作期间,才会往selected-key集合加入keys。可以通过Set的remove或是Iterator的remove方法可以将selected-key集合里面的key移除。Keys不能直接的加入selected-key集合,除非是在selection发生期间。

在每个selection操作期间,selector关联的selected-key集合都可能加入和移除key。当调用selector的select(),select(long)或是selectNow()方法的时候,会触发selection操作。在此期间会触发三个步骤。

第一步
将在canceled-key 集合里面的key在selecor关联的三个key set集合里面移除(如果是其中的成员的话),经过这一步,cancelled-key集合会被清空。

第二步 操作系统会查询更新那些已经触发了感兴趣事件的channel到 ready 态。
1 如果上面查询出来的key(可以同认为是关联的channel)不在selected-key集合里面,此key将会添加到selected-key集合里面,并将已经发生的兴趣事件被更新到ready-operation set集合,ready-operation set集合先前的值会被清空。

2如果查询出来的key已经在selected-key里面,那么新的感兴趣事件会与原先的感兴趣事件的 并集存储到ready-operation set。

如果key set集合里面的channel没有在selector上面注册感兴趣事件,那么selected-key集合的ready-operation set不会做任何的更新。

Selector本身是线程安全的,但是其key set集合不是的。
由于key可以被随时的取消,channel也可以被随时的关闭,即使我们selector的key集合里面看到了某个key,也不能认为此key是安全的,或其关联的channel是open状态。由于其他的线程随时可以取消一个key或是关闭一个channel,应用代码应该格外的小心的对其状态进行校验。

当一个线程在调用 select()或是select(long)方法堵塞的时候,可以被其他线程已以下三种情况中断。

被其他的线程调用了 wakeup方法
被其他线程调用了close方法
调用当前堵塞线程的interrupt方法,这时被堵塞线程的中断状态会被重置,继而wakeup方法会被触发。

在并发场景下,总的来说,key set集合和 selected-key集合都不是线程安全的,必须进行同步控制。

//=========================================
SelectionKey表征了SelectableChannel与Selector的注册关系
当一个channel注册到selector上的时候会创建一个selectionkey出来,除非调用selectionkey的cancel方法,或者关闭channel或者关闭selector,selectionkey始终有效。
取消一个selectionkey的时候不会立即的从其关联的selector上面移除掉,其会立即的添加到selector关联的cancelled-key集合里面去,下次selection操作期间,会从selector关联的三个集合里面都移除掉。
通过调用isValid方法可以测试key是否有效。
Selection key用两个整数来代表两个操作集合,每个整数的每个bit位代表其key关联的channel支持的 selectable 操作。

Interest set在key被创建的时候被初始化,可以通过interestOps(int)方法进行修改。其表征了在selector进行selection操作期间channel注册的感兴趣的操作。
Ready set属于interest set的子集,表征了在selector在进行selection操作期间在interest set上检测到的已经准备好的操作。

Selection key 的 ready set按时着此channel已经准备好进行进行某些网络操作,但是也不一定,因为其他线程也可以对此channel进行取消的操作,所以在检测到ready set有值之后,应该尽快的进行相关操作。

selelctionkey类定义了一些通用的位操作,但是selectionKey的不同的子类可以定义自己独特的位操作,如果定义了某个子类不支持的位操作,会报运行时错误。
SelelctKey的attach方法可以绑定一些业务数据来表征某些别的信息。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容