成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java NIO類庫Selector機制解析(下)

開發 后端
自從J2SE 1.4版本以來,JDK發布了全新的I/O類庫,簡稱NIO,其不但引入了全新的高效的I/O機制,同時,也引入了多路復用的異步模式。

五、 迷惑不解 : 為什么要自己消耗資源?

令人不解的是為什么我們的Java的New I/O要設計成這個樣子?如果說老的I/O不能多路復用,如下圖所示,要開N多的線程去挨個偵聽每一個Channel (文件描述符) ,如果這樣做很費資源,且效率不高的話。那為什么在新的I/O機制依然需要自己連接自己,而且,還是重復連接,消耗雙倍的資源?

通過WEB搜索引擎沒有找到為什么。只看到N多的人在報BUG,但SUN卻沒有任何解釋。

下面一個圖展示了,老的IO和新IO的在網絡編程方面的差別。看起來NIO的確很好很強大。但似乎比起C/C++來說,Java的這種實現會有一些不必要的開銷。

六、 它山之石 : 從Apache的Mina框架了解Selector

上面的調查沒過多長時間,正好同學趙錕的一個同事也在開發網絡程序,這位仁兄使用了Apache的Mina框架。當我們把Mina框架的源碼研讀了一下后。發現在Mina中有這么一個機制:

1)Mina框架會創建一個Work對象的線程。

2)Work對象的線程的run()方法會從一個隊列中拿出一堆Channel,然后使用Selector.select()方法來偵聽是否有數據可以讀/寫。

3)最關鍵的是,在select的時候,如果隊列有新的Channel加入,那么,Selector.select()會被喚醒,然后重新select***的Channel集合。

4)要喚醒select方法,只需要調用Selector的wakeup()方法。

對于熟悉于系統調用的C/C++程序員來說,一個阻塞在select上的線程有以下三種方式可以被喚醒:

1) 有數據可讀/寫,或出現異常。

2) 阻塞時間到,即time out。

3) 收到一個non-block的信號。可由kill或pthread_kill發出。

所以,Selector.wakeup()要喚醒阻塞的select,那么也只能通過這三種方法,其中:

1)第二種方法可以排除,因為select一旦阻塞,應無法修改其time out時間。

2)而第三種看來只能在Linux上實現,Windows上沒有這種信號通知的機制。

所以,看來只有***種方法了。再回想到為什么每個Selector.open(),在Windows會建立一對自己和自己的loopback的TCP連接;在Linux上會開一對pipe(pipe在Linux下一般都是成對打開),估計我們能夠猜得出來——那就是如果想要喚醒select,只需要朝著自己的這個loopback連接發點數據過去,于是,就可以喚醒阻塞在select上的線程了。

七、 真相大白 : 可愛的Java你太不容易了

使用Linux下的strace命令,我們可以方便地證明這一點。參看下圖。圖中,請注意下面幾點:

1) 26654是主線程,之前我輸出notify the select字符串是為了做一個標記,而不至于迷失在大量的strace log中。

2) 26662是偵聽線程,也就是select阻塞的線程。

3) 圖中選中的兩行。26654的write正是wakeup()方法的系統調用,而緊接著的就是26662的epoll_wait的返回。

從上圖可見,這和我們之前的猜想正好一樣。可見,JDK的Selector自己和自己建的那些TCP連接或是pipe,正是用來實現Selector的notify和wakeup的功能的。

這兩個方法完全是來模仿Linux中的的kill和pthread_kill給阻塞在select上的線程發信號的。但因為發信號這個東西并不是一個跨平臺的標準(pthread_kill這個系統調用也不是所有Unix/Linux都支持的),而pipe是所有的Unix/Linux所支持的,但Windows又不支持,所以,Windows用了TCP連接來實現這個事。

關于Windows,我一直在想,Windows的防火墻的設置是不是會讓Java的類似的程序執行異常呢?呵呵。如果不知道Java的SDK有這樣的機制,誰知道會有多少個程序為此引起的問題度過多少個不眠之夜,尤其是Java程序員。

八、 后記

文章到這里是可以結束了,但關于Java NIO的Selector引出來的其它話題還有許多,比如關于GNU 的Java編譯器又是如何,它是否會像Sun的Java解釋器如此做傻事?我在這里先賣一個關子,關于GNU的Java編譯器,我會在另外一篇文章中講述,近期發布,敬請期待。

關于本文中所使用的實驗平臺如下:

◆  Windows:Windows XP + SP2, Sun J2SE (build 1.7.0-ea-b23)

◆  Linux:Ubuntu 7.10 + Linux Kernel 2.6.22-14-generic, J2SE (build 1.6.0_03-b05)

本文主要的調查工作由我的大學同學趙錕完成,我幫其驗證調查成果及猜想。在此也向大家介紹我的大學同學趙錕,他也是一個技術高手,在軟件開發方面,特別是Unix/Linux C/C++方面有著相當的功底,相信自此以后,會有很多文章會由我和他一同發布。

本篇文章由我成文。但其全部著作權和版權歸趙錕和我共同所有。我們歡迎大家轉載,但希望保持整篇文章的完整性,并請勿用于任何商業用途。謝謝。

原文鏈接:http://haoel.blog.51cto.com/313033/124578

【編輯推薦】

  1. Java NIO類庫Selector機制解析(上)
  2. Java的NIO以及線程并發
  3. 基于事件的NIO多線程服務器
  4. Java NIO的多路復用及reactor
  5. 在Java中使用NIO進行網絡編程
責任編輯:林師授 來源: 陳皓的個人博客
相關推薦

2011-12-12 10:19:00

JavaNIO

2022-02-22 08:00:48

JavaNIOBuffer

2011-12-07 15:58:25

JavaNIO

2011-12-08 10:24:53

JavaNIO

2025-02-28 09:14:09

JavaNIO機制

2011-11-23 09:39:33

JavaClassLOader機制

2010-01-25 17:28:18

Android類庫

2011-03-16 09:26:41

ReadWriteLoJava

2010-09-17 13:02:11

JAVA反射機制

2015-10-26 09:25:42

2021-07-05 06:51:43

Java機制類加載器

2011-07-01 15:04:49

Qt 內省

2022-03-24 13:36:18

Java悲觀鎖樂觀鎖

2024-05-27 08:04:41

2010-10-13 10:24:38

垃圾回收機制JVMJava

2011-12-15 09:40:06

Javanio

2011-12-07 14:57:44

JavaNIO

2011-12-15 09:55:47

javanio

2011-12-15 11:19:08

JavaNIO

2011-08-02 18:07:03

iPhone 內省 Cocoa
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区二区久久 | 国产精品久久久久久久7电影 | 日韩高清黄色 | 久久国产精品免费一区二区三区 | 精品三级在线观看 | 午夜精品久久久久久不卡欧美一级 | 免费一区在线 | 国产精品一级 | 亚洲欧洲精品成人久久奇米网 | 日韩电影一区二区三区 | 亚洲免费一区 | 亚洲精彩视频在线观看 | 国产精品国产精品国产专区不卡 | 亚洲欧美一区二区三区国产精品 | 在线国产视频 | 玖玖国产精品视频 | 亚洲综合区 | av中文字幕在线观看 | 国产一区二区三区四区 | 国产黄色在线观看 | 天天插天天操 | 91精品国产综合久久久久久丝袜 | 日韩三区| 久在线| 欧美成年黄网站色视频 | 大学生a级毛片免费视频 | 国产免费一区二区 | 欧美亚州综合 | 成人福利在线 | 久久精品欧美一区二区三区不卡 | 亚洲精品68久久久一区 | 国产精品一区二区在线 | 国产精品高潮呻吟久久av黑人 | 精品成人av| 亚洲二区视频 | 久久久久国产一区二区三区 | 精品一区二区三区电影 | 一区二区日韩精品 | 成人视屏在线观看 | 精品日韩一区二区 | 999久久久久久久 |