国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Java NIO的wakeup剖析

開發(fā) 后端
java NIO的實現(xiàn)中,有不少細節(jié)點非常有學習意義的,本文主要講解從Selector的 wakeup原理是什么?是如何實現(xiàn)的?

java NIO的實現(xiàn)中,有不少細節(jié)點非常有學習意義的,就好比下面的這個點:

Selector的 wakeup原理是什么?是如何實現(xiàn)的?

wakeup()

準確來說,應(yīng)該是Selector的wakeup(),即Selector的喚醒,為什么要有這個喚醒操作呢?那還得從Selector的選擇方式 來說明,前文已經(jīng)總結(jié)過Selector的選擇方式有三種:select()、select(timeout)、selectNow()。
selectNow的選擇過程是非阻塞的,與wakeup沒有太大關(guān)系。

select(timeout)和select()的選擇過程是阻塞的,其他線程如果想終止這個過程,就可以調(diào)用wakeup來喚醒。

wakeup的原理

既然Selector阻塞式選擇因為找到感興趣事件ready才會返回(排除超時、中斷),就給它構(gòu)造一個感興趣事件ready的場景即可。下圖可以比較形象的形容wakeup原理:

Selector管轄的FD(文件描述符,linux即為fd,對應(yīng)一個文件,windows下對應(yīng)一個句柄;每個可選擇Channel在創(chuàng)建的時 候,就生成了與其對應(yīng)的FD,Channel與FD的聯(lián)系見另一篇)中包含某一個FD A, A對數(shù)據(jù)可讀事件感興趣,當往圖中漏斗端放入(寫入)數(shù)據(jù),數(shù)據(jù)會流進A,于是A有感興趣事件ready,最終,select得到結(jié)果而返回。

wakeup在Selector中的定義如下:

  1. public abstract Selector wakeup(); 

下面結(jié)合上圖來追尋wakeup的實現(xiàn):

linux下Selector默認實現(xiàn)為PollSelectorImpl,當內(nèi)核版本大于2.6時,實現(xiàn)為EPollSelectorImpl,僅看這兩者的wakeup方法,代碼似乎完全一樣:

  1. public Selector wakeup() { 
  2.     synchronized (interruptLock) { 
  3.         if (!interruptTriggered) { 
  4.             pollWrapper.interrupt(); 
  5.             interruptTriggered = true
  6.         } 
  7.     } 
  8.     return this

window下Selector的實現(xiàn)為WindowsSelectorImpl,其wakeup實現(xiàn)如下:

  1. public Selector wakeup() { 
  2.     synchronized (interruptLock) { 
  3.         if (!interruptTriggered) { 
  4.             setWakeupSocket(); 
  5.             interruptTriggered = true
  6.         } 
  7.     } 
  8.     return this

其中interruptTriggered為中斷已觸發(fā)標志,當pollWrapper.interrupt()之后,該標志即為true了;得益于這個標志,連續(xù)兩次wakeup,只會有一次效果。

對比上圖及上述代碼,其實pollWrapper.interrupt()及setWakeupSocket()就是圖中的往漏斗中倒水的過程,不 管windows也好,linux也好,它們wakeup的思想是完全一致的,不同的地方就在于實現(xiàn)的細節(jié)了,例如上圖中漏斗與通道的鏈接部 分,linux下是采用管道pipe來實現(xiàn)的,而windows下是采用兩個socket之間的通訊來實現(xiàn)的,它們都有這樣的特性:

1)都有兩個端,一個 是read端,一個是write端,windows中兩個socket也是一個扮演read的角色,一個扮演write的角色;

2)當往write端寫入 數(shù)據(jù),則read端即可以收到數(shù)據(jù);從它們的特性可以看出,它們是能夠勝任這份工作的。

如果只想理解wakeup的原理,看到這里應(yīng)該差不多了,不過,下面,想繼續(xù)深入一下,滿足更多人的好奇心。

先看看linux下PollSelector的具體wakeup實現(xiàn),分階段來介紹:

1) 準備階段

PollSelector在構(gòu)造的時候,就將管道pipe,及wakeup專用FD給準備好,可以看一下它的實現(xiàn):

  1. PollSelectorImpl(SelectorProvider sp) { 
  2.     super(sp, 1, 1); 
  3.     int[] fdes = new int[2]; 
  4.     IOUtil.initPipe(fdes, false); 
  5.     fd0 = fdes[0]; 
  6.     fd1 = fdes[1]; 
  7.     pollWrapper = new PollArrayWrapper(INIT_CAP); 
  8.     pollWrapper.initInterrupt(fd0, fd1); 
  9.     channelArray = new SelectionKeyImpl[INIT_CAP]; 

IOUtil.initPipe,采用系統(tǒng)調(diào)用pipe(int fd[2])來創(chuàng)建管道,fd[0]即為ready端,fd[1]即為write端。

另一個需要關(guān)注的點就是pollWrapper.initInterrupt(fd0, fd1),先看一下它的實現(xiàn):

  1. void initInterrupt(int fd0, int fd1) { 
  2.     interruptFD = fd1; 
  3.     putDescriptor(0, fd0); 
  4.     putEventOps(0, POLLIN); 
  5.     putReventOps(00); 

以看到,initInterrupt在準備wakeup專用FD,因為fd0是read端fd,fd1是write端fd:

interruptFD被初始化為write端fd;

putDescriptor(0, fd0)初始化pollfd數(shù)組中的***個pollfd,即指PollSelector關(guān)注的***個fd,即為fd0;

putEventOps(0, POLLIN)初始化fd0對應(yīng)pollfd中的events為POLLIN,即指fd0對可讀事件感興趣;

putReventOps(0, 0)只是初始化一下fd0對應(yīng)的pollfd中的revents;

2) 執(zhí)行階段

有了前面的準備工作,就看PollArrayWrapper中的interrupt()實現(xiàn):

  1. public void interrupt() { 
  2.     interrupt(interruptFD); 

interrupt是native方法,它的入?yún)nterruptFD即為準備階段管道的write端fd,對應(yīng)于上圖,其實就是漏斗端,因此,就是不看其實現(xiàn),也知道它肯定扮演著倒水的這個動作,看其實現(xiàn):

  1. JNIEXPORT void JNICALL 
  2. Java_sun_nio_ch_PollArrayWrapper_interrupt(JNIEnv *env, jobject this, jint fd) 
  3.     int fakebuf[1]; 
  4.     fakebuf[0] = 1; 
  5.     if (write(fd, fakebuf, 1) < 0) { 
  6.          JNU_ThrowIOExceptionWithLastError(env, 
  7.                                           "Write to interrupt fd failed"); 
  8.     } 

可以看出,interrupt(interruptFD)是往管道的write端fd1中寫入一個字節(jié)(write(fd, fakebuf, 1))。

是的,只需要往fd1中寫入一個字節(jié),fd0即滿足了可讀事件ready,則Selector自然會因為有事件ready而中止阻塞返回。

EPollSelector與PollSelector相比,其wakeup實現(xiàn)就只有initInterrupt不同,它的實現(xiàn)如下:

  1. void initInterrupt(int fd0, int fd1) { 
  2.     outgoingInterruptFD = fd1; 
  3.     incomingInterruptFD = fd0; 
  4.     epollCtl(epfd, EPOLL_CTL_ADD, fd0, EPOLLIN); 

epfd之前的篇章里已經(jīng)講過,它是通過epoll_create創(chuàng)建出來的epoll文件fd,epollCtl調(diào)用內(nèi)核epoll_ctl實現(xiàn)了往epfd上添加fd0,且其感興趣事件為可讀(EPOLLIN)。

因此可以斷定,EPollSelector與PollSelector的wakeup實現(xiàn)是一致的。

因為之前一直專注與分析linux下的Java NIO實現(xiàn),忽略了windows下的選擇過程等,這里突然講解其wakeup實現(xiàn)似乎很突兀,所以打算后面專門起一篇來介紹windows下的NIO實 現(xiàn),這里我們只需要理解wakeup原理,甚至自己去看看其wakeup實現(xiàn),應(yīng)該也沒什么難度。

關(guān)于wakeup,這里還有兩個疑問:

為什么wakeup方法返回Selector?

windows下也是有pipe的,為什么使用socket而不是使用pipe來實現(xiàn)wakeup的?

也歡迎大家留下自己的想法,一起討論。

原文鏈接:http://goldendoc.iteye.com/blog/1152079

【編輯推薦】

  1. Java NIO類庫關(guān)系圖解
  2. 淺析Tomcat NIO 配置
  3. Java NIO API詳解
  4. Java NIO基本使用實例
  5. Java NIO的介紹及工作原理
責任編輯:林師授 來源: goldendoc的博客
相關(guān)推薦

2024-05-27 08:04:41

2011-12-08 13:23:00

JavaNIO

2011-12-15 09:40:06

Javanio

2011-12-15 11:19:08

JavaNIO

2011-12-07 14:57:44

JavaNIO

2011-12-15 09:55:47

javanio

2011-12-13 09:12:34

JavaNIO

2011-12-07 14:25:33

JavaNIO

2022-02-22 08:00:48

JavaNIOBuffer

2011-12-15 10:43:20

JavaNIO

2011-12-15 10:10:33

Javanio

2011-12-07 14:41:51

JavaNIO

2015-09-25 09:14:50

java緩沖技術(shù)

2011-12-15 12:32:19

JavaNIO

2011-12-08 10:51:25

JavaNIO

2025-08-26 02:24:00

JavaI/O模型

2011-12-07 15:58:25

JavaNIO

2011-12-15 11:11:51

JavaNIO

2011-12-14 10:31:43

2011-12-02 13:16:14

JavaNIO
點贊
收藏

51CTO技術(shù)棧公眾號

欧美性xxxxxxxxx| 激情aⅴ欧美一区二区欲海潮| 日韩免费在线电影| 在线观看亚洲精品| 自拍偷拍21p| 久久狠狠婷婷| 91在线直播亚洲| 24小时成人在线视频| 精品国产sm最大网站免费看| 在线看黄网站| 亚洲免费在线视频一区 二区| 99中文字幕在线观看| 国产欧美短视频| 成人18视频| 欧美高清视频手机在在线| 九九热精品视频| 中文字幕在线视频网站| 日韩成人在线播放| 欧美24videosex性欧美| 亚洲精品wwwww| 涩涩av在线| 亚洲图中文字幕| 成人爱爱网址| 一区二区亚洲精品国产| 成人看片网页| 日日骚av一区| 国产成人精品福利| 欧洲精品毛片网站| 欧美丝袜丝交足nylons172| 国产精品一区二区三区毛片淫片| 日韩精品免费| 国产女人水真多18毛片18精品| 亚洲精品综合| 自拍日韩亚洲一区在线| 久久欧美肥婆一二区| 国产对白在线播放| 91色综合久久久久婷婷| 毛片毛片毛片毛片| 在线观看欧美日韩国产| 黄色网址在线免费| 色婷婷av一区二区三区软件| 亚洲高清不卡一区| 亚洲日本va| 精品国产一区二区三区四区四| 亚洲不卡中文字幕无码| 91高清一区| 久久精品99久久久香蕉| 男人资源在线播放| 成人免费观看av| 国产精品午夜国产小视频| 爽爽淫人综合网网站| 色8久久久久| 小草在线视频在线免费视频| 久久天天东北熟女毛茸茸| 伊人激情综合网| 午夜欧美巨大性欧美巨大 | 久久嫩草精品久久久精品| 97色伦亚洲国产| 麻豆免费在线| 欧美性猛交xxxx富婆| 亚洲成人网上| gogo大胆日本视频一区| 日韩在线导航| 一区在线免费观看| 欧美亚洲日本网站| 欧美成年网站| 国产亚洲一级高清| 久久精品国产大片免费观看| 亚洲成人网在线观看| 中文字幕在线永久在线视频| 亚洲女女做受ⅹxx高潮| 99久久无色码| 久久草在线视频| 国产成人极品视频| 欧美人与牛zoz0性行为| 日韩一区二区三区高清| 一区二区三区资源| 日本黄色免费在线| 中日韩美女免费视频网址在线观看 | 隔壁老王国产在线精品| 日本一区二区在线看| 黄色激情在线视频| 亚洲成人黄色网| 午夜一级在线看亚洲| 国产v日韩v欧美v| 国产精品麻豆免费版| 欧美日韩日日摸| 另类av一区二区| 成人日批视频| 在线观看成人免费| 日韩在线中文字| 亚洲女人****多毛耸耸8| 欧美一区 二区| 中文字幕一区二区三区域| 国产精品久久国产精品| 在线综合亚洲欧美在线视频 | 成人欧美一区二区三区视频xxx| 欧美男同性恋视频网站| 国产一区二区在线观看视频| 91精品国产自产精品男人的天堂| 免费观看的av网站| 免费亚洲精品视频| 国产小视频91| 亚洲一区视频在线| 久久se精品一区二区| 日韩中文一区二区| 欧美精品久久久久久久久久丰满| 欧美黑人又粗又大又爽免费| 亚洲成人综合网站| 精品影片在线观看的网站| 色网站免费在线观看| 日韩精品视频久久| 国产一区二区视频在线免费观看| 欧美精品免费视频| 国产精品久久久久影院色老大| 欧美日韩一卡| 欧美a级网站| 成人视屏在线观看| 激情综合闲人网| 手机在线看福利| 欧美日韩一区在线观看视频| 欧美激情亚洲国产| 日韩精品中文字幕在线观看 | 乱子伦一区二区| 国产偷国产偷亚洲高清97cao| 欧美成人三级视频网站| 精品久久国产老人久久综合| 国产精品久久久久影院色老大| 久久精品国产精品青草| 午夜日韩激情| 99九九热只有国产精品| caoporn成人免费视频在线| 日韩影视在线| 麻豆网在线观看| 国产1区2区3区在线| 日本福利片免费看| 99热在线免费| 91视频免费版污| 免费一级特黄毛片| 青青草国产免费| 成人在线播放网址| 欧美一级片免费播放| 国产成人生活片| 日本人妻伦在线中文字幕| 国产又粗又长又爽视频| 国产又粗又大又爽的视频| 日韩不卡一二区| 青草青青在线视频| 少妇高清精品毛片在线视频| 日本888xxxx| 午夜影院在线观看视频| 爱爱爱免费视频在线观看| 影音先锋男人在线资源| 亚洲黄色免费av| 欧美视频三区| 精品盗摄女厕tp美女嘘嘘| 少妇精品久久久一区二区三区| 九九热线有精品视频99| 激情五月***国产精品| 极品美女销魂一区二区三区免费| 懂色一区二区三区免费观看| 久久久国产精品午夜一区ai换脸| 亚洲九九爱视频| 日韩视频在线你懂得| 在线电影中文日韩| 情事1991在线| 日本视频一区在线观看| 狠狠热免费视频| 欧美在线观看视频| 精品国产日本| 精品国产成人av在线免| 中文字幕在线影视资源| 波多野结衣在线播放| 草草视频在线一区二区| 99亚洲视频| 国产精品传媒在线| 日韩天堂在线观看| 国产成人综合av| 国产高清不卡无码视频| 九色在线观看| 国产精品香蕉| 久久电影国产免费久久电影| 中文字幕中文字幕中文字幕亚洲无线| 欧美日韩一级二级三级| 97视频com| 在线观看18视频网站| 加勒比一区二区三区在线| 欧美专区视频| 国产精品99久久久久久久女警| 欧美亚洲综合另类| 国产精品稀缺呦系列在线| 国产一级特黄a大片免费| caoporn视频在线| 亚洲韩日在线| 精品日韩中文字幕| 国产精品第二页| 探花国产精品| 久久久伦理片| 国产精品久久久久久福利一牛影视| 国产一区二区三区直播精品电影|