<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      深入理解Java NIO

      初識NIO:

          在 JDK 1. 4 中 新 加入 了 NIO( New Input/ Output) 類, 引入了一種基于通道和緩沖區的 I/O 方式,它可以使用 Native 函數庫直接分配堆外內存,然后通過一個存儲在 Java 堆的 DirectByteBuffer 對象作為這塊內存的引用進行操作,避免了在 Java 堆和 Native 堆中來回復制數據。

          NIO 是一種同步非阻塞的 IO 模型。同步是指線程不斷輪詢 IO 事件是否就緒,非阻塞是指線程在等待 IO 的時候,可以同時做其他任務。同步的核心就是 Selector,Selector 代替了線程本身輪詢 IO 事件,避免了阻塞同時減少了不必要的線程消耗;非阻塞的核心就是通道和緩沖區,當 IO 事件就緒時,可以通過寫道緩沖區,保證 IO 的成功,而無需線程阻塞式地等待。

      Buffer:

          為什么說NIO是基于緩沖區的IO方式呢?因為,當一個鏈接建立完成后,IO的數據未必會馬上到達,為了當數據到達時能夠正確完成IO操作,在BIO(阻塞IO)中,等待IO的線程必須被阻塞,以全天候地執行IO操作。為了解決這種IO方式低效的問題,引入了緩沖區的概念,當數據到達時,可以預先被寫入緩沖區,再由緩沖區交給線程,因此線程無需阻塞地等待IO。

      通道:

          當執行:SocketChannel.write(Buffer),便將一個 buffer 寫到了一個通道中。如果說緩沖區還好理解,通道相對來說就更加抽象。網上博客難免有寫不嚴謹的地方,容易使初學者感到難以理解。

          引用 Java NIO 中權威的說法:通道是 I/O 傳輸發生時通過的入口,而緩沖區是這些數 據傳輸的來源或目標。對于離開緩沖區的傳輸,您想傳遞出去的數據被置于一個緩沖區,被傳送到通道。對于傳回緩沖區的傳輸,一個通道將數據放置在您所提供的緩沖區中。

          例如 有一個服務器通道 ServerSocketChannel serverChannel,一個客戶端通道 SocketChannel clientChannel;服務器緩沖區:serverBuffer,客戶端緩沖區:clientBuffer。

          當服務器想向客戶端發送數據時,需要調用:clientChannel.write(serverBuffer)。當客戶端要讀時,調用 clientChannel.read(clientBuffer)

          當客戶端想向服務器發送數據時,需要調用:serverChannel.write(clientBuffer)。當服務器要讀時,調用 serverChannel.read(serverBuffer)

          這樣,通道和緩沖區的關系似乎更好理解了。在實踐中,未必會出現這種雙向連接的蠢事(然而這確實存在的,后面的內容還會涉及),但是可以理解為在NIO中:如果想將Data發到目標端,則需要將存儲該Data的Buffer,寫入到目標端的Channel中,然后再從Channel中讀取數據到目標端的Buffer中。

      Selector:

          通道和緩沖區的機制,使得線程無需阻塞地等待IO事件的就緒,但是總是要有人來監管這些IO事件。這個工作就交給了selector來完成,這就是所謂的同步。

          Selector允許單線程處理多個 Channel。如果你的應用打開了多個連接(通道),但每個連接的流量都很低,使用Selector就會很方便。

          要使用Selector,得向Selector注冊Channel,然后調用它的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒,這就是所說的輪詢。一旦這個方法返回,線程就可以處理這些事件。

          Selector中注冊的感興趣事件有:

      • OP_ACCEPT

      • OP_CONNECT 

      • OP_READ 

      • OP_WRITE

      優化:

          一種優化方式是:將Selector進一步分解為Reactor,將不同的感興趣事件分開,每一個Reactor只負責一種感興趣的事件。這樣做的好處是:1、分離阻塞級別,減少了輪詢的時間;2、線程無需遍歷set以找到自己感興趣的事件,因為得到的set中僅包含自己感興趣的事件。

      NIO和epoll:

          epoll是Linux內核的IO模型。我想一定有人想問,AIO聽起來比NIO更加高大上,為什么不使用AIO?AIO其實也有應用,但是有一個問題就是,Linux是不支持AIO的,因此基于AIO的程序運行在Linux上的效率相比NIO反而更低。而Linux是最主要的服務器OS,因此相比AIO,目前NIO的應用更加廣泛。

          說到這里,可能你已經明白了,epoll一定和NIO有著很深的因緣。沒錯,如果仔細研究epoll的技術內幕,你會發現它確實和NIO非常相似,都是基于“通道”和緩沖區的,也有selector,只是在epoll中,通道實際上是操作系統的“管道”。和NIO不同的是,NIO中,解放了線程,但是需要由selector阻塞式地輪詢IO事件的就緒;而epoll中,IO事件就緒后,會自動發送消息,通知selector:“我已經就緒了?!笨梢哉J為,Linux的epoll是一種效率更高的NIO。

      NIO軼事:

          一篇有意思的博客,講的 Java selector.open() 的時候,會創建一個自己和自己的鏈接(windows上是tcp,linux上是通道)

          這么做的原因:可以從 Apache Mina 中窺探。在 Mina 中,有如下機制:

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

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

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

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

          而一個阻塞在select上的線程有以下三種方式可以被喚醒:

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

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

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

          首先 2 可以排除,而第三種方式,只在linux中存在。因此,Java NIO為什么要創建一個自己和自己的鏈接:就是如果想要喚醒select,只需要朝著自己的這個loopback連接發點數據過去,于是,就可以喚醒阻塞在select上的線程了。

      posted @ 2016-08-15 19:21  Geason崔  閱讀(71191)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 免费网站看av片| 镇坪县| 亚洲区日韩精品中文字幕| 亚洲一区二区在线av| 亚洲欧美成人久久综合中文网| 正在播放肥臀熟妇在线视频| 在线国产极品尤物你懂的| 国产午夜福利片在线观看| 国产裸体无遮挡免费精品| 日韩免费码中文在线观看| 嘉鱼县| 国产亚洲精品久久久久久无亚洲 | 无码人妻一区二区三区AV| 国产亚洲精品成人av久| 久热伊人精品国产中文| 亚洲欧美一区二区三区图片| 国产成人综合色视频精品| 国产91久久精品一区二区| 成人欧美一区二区三区在线观看| 亚洲一区二区三区水蜜桃| 依依成人精品视频在线观看| 亚洲成在人线在线播放无码| 91久久亚洲综合精品成人| 日本一道一区二区视频| 色九月亚洲综合网| 国产精品一区二区久久毛片| 2020久久香蕉国产线看观看| 洱源县| 玩弄放荡人妻少妇系列 | 色综合视频一区二区三区| 俄罗斯老熟妇性爽xxxx| 精品国产乱码久久久久夜深人妻| 激情五月日韩中文字幕| 日韩一区二区三区日韩精品| 国产精品自在自线视频| 日韩高清福利视频在线观看| 国产一区二区精品自拍| 色老头亚洲成人免费影院| japan黑人极大黑炮| 繁峙县| 亚洲精品一品二品av|