老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

如何進行JavaNIO的wakeup剖析

如何進行Java NIO的wakeup剖析,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

公司主營業務:成都網站建設、成都網站設計、移動網站開發等業務。幫助企業客戶真正實現互聯網宣傳,提高企業的競爭能力。創新互聯公司是一支青春激揚、勤奮敬業、活力青春激揚、勤奮敬業、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰,讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創新互聯公司推出烏蘭免費做網站回饋大家。

java NIO的實現中,有不少細節點非常有學習意義的,就好比下面的這個點:

Selector的 wakeup原理是什么?是如何實現的?

wakeup()

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

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

wakeup的原理

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

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

wakeup在Selector中的定義如下:

public abstract Selector wakeup();

下面結合上圖來追尋wakeup的實現:

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

public Selector wakeup() {     synchronized (interruptLock) {         if (!interruptTriggered) {             pollWrapper.interrupt();             interruptTriggered = true;         }     }     return this; }

window下Selector的實現為WindowsSelectorImpl,其wakeup實現如下:

public Selector wakeup() {     synchronized (interruptLock) {         if (!interruptTriggered) {             setWakeupSocket();             interruptTriggered = true;         }     }     return this; }

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

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

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

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

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

先看看linux下PollSelector的具體wakeup實現,分階段來介紹:

1)準備階段

PollSelector在構造的時候,就將管道pipe,及wakeup專用FD給準備好,可以看一下它的實現:

PollSelectorImpl(SelectorProvider sp) {     super(sp, 1, 1);     int[] fdes = new int[2];     IOUtil.initPipe(fdes, false);     fd0 = fdes[0];     fd1 = fdes[1];     pollWrapper = new PollArrayWrapper(INIT_CAP);     pollWrapper.initInterrupt(fd0, fd1);     channelArray = new SelectionKeyImpl[INIT_CAP]; }

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

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

void initInterrupt(int fd0, int fd1) {     interruptFD = fd1;     putDescriptor(0, fd0);     putEventOps(0, POLLIN);     putReventOps(0, 0); }

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

interruptFD被初始化為write端fd;

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

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

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

2)執行階段

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

public void interrupt() {     interrupt(interruptFD); }

interrupt是native方法,它的入參interruptFD即為準備階段管道的write端fd,對應于上圖,其實就是漏斗端,因此,就是不看其實現,也知道它肯定扮演著倒水的這個動作,看其實現:

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

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

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

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

void initInterrupt(int fd0, int fd1) {     outgoingInterruptFD = fd1;     incomingInterruptFD = fd0;     epollCtl(epfd, EPOLL_CTL_ADD, fd0, EPOLLIN); }

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

因此可以斷定,EPollSelector與PollSelector的wakeup實現是一致的。

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

關于如何進行Java NIO的wakeup剖析問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創新互聯行業資訊頻道了解更多相關知識。


網站標題:如何進行JavaNIO的wakeup剖析
網站URL:http://www.xueling.net.cn/article/pssheh.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 久久久久久久久久久高潮 | 波多野结衣无码视频在线观看 | 亚洲午夜无码毛片av久久 | 九色com| 久久亚洲精品国产精品 | 久久久久亚洲Aⅴ无码 | 久章草在线无码视频观看 | 亚洲欧美一区二区精品久久久 | 在线视频欧美一区 | 国产午夜亚洲精品国产成人小说 | 久久色成人在线 | 久操线在视频在线观看 | 2024丁香五月天之婷婷综合缴情 | 国产a一级毛片爽爽影院 | 99pao成人国产永久免费视频 | 色老头永久免费视频 | www日韩高清 | 韩国三级在线观看久 | 日本一级黄色录像 | 在线欧美小视频 | 超碰在线观看97 | 国色天香色欲色欲综合网 | 欧美级毛片 | 成人免费观看网址 | 中文无码AV一区二区三区 | 熟女人妻aⅴ一区二区三区60路 | 久色免费视频 | 久精品国产欧美亚洲色aⅴ大片 | 久久夜亚洲| 成年人视频在线免费看 | gogo全球大胆高清人露出91 | 91香蕉国产在线观看免费永久 | 国产精品VA在线观看无码不卡 | 国产精品嫩草影院9 | 久久久久国产精品熟女影院 | 亚洲人精品 | 成人性视频免费网站 | 亚洲欧美国产国产一区二区三区 | 中文字幕亚洲乱码熟女在线萌芽 | 欧美丰满少妇XXXX性 | 欧美日韩成人一区二区三区 |