<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                實際工作中,使用Java IO的API來操作文件的機會并不多,更多的時候只需要配置文件(xml , properties)放到指定的位置,剩下的工作就交給框架來處理,框架會把配置數據變成Java對象來調用,不用操心IO細節。 其實IO就是輸入輸出的意思,文件只是一個IO的例子而已。從網絡讀寫數據也是IO,IO是對他們的抽象。 我們把的自己當做是程序,從外面讀數據的時候就用InputStream,向外邊寫數據的時候就用OutputStream Stream 這個詞也很有意思,想象一下,你從文件 / 網絡讀取數據, 這些數據像河流一樣 “流” 向你, 是不是很形象? 由于是“流”, 你讀到了第 100 個字節, 然后想退回到第 10 個字節重新讀, 那我是不允許的, 河流是不允許倒退的。 但是計算機中的一切都是二進制字節,但是如果直接使用InputStream或者OutputStream來讀文本內容,會有些麻煩,還得翻譯成字符,所以Java提供了Reader/Writer接口,專門用于櫥窗字符流。 ## 阻塞 IO API的最大問題在于阻塞,比如讀取文件中的一行數據 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180823091704.png?picgo) 當一個線程在執行這段代碼的時候,遇到了readLine()方法的時候,需要等待數據從硬盤進入內存。 這個線程就會被阻塞。 人們想把它改為非阻塞,也就是調用了readLine()之后,立刻就煩這,線程就可以干其他事去了。 但是線程不就是為了讀數據嗎,如果變成了非阻塞,調用了readLine()之后,線程可以執行后面的代碼,那這個線程豈不是還得做個輪詢操作,看看數據是否已讀好了。 要是線程打開了成百上千個文件,使用阻塞的方式,只能按照文件1、文件2這樣的順序去讀取,太慢了,如果是非阻塞二方式可以同時發起成百上千個讀操作,然后在循環中檢查, 看誰的數據處理好了,就讀誰的。 這種情況常見于Socket編程,一個Socket來了,就創建一個新的線程或者從線程池分配一個線程去處理這個連接,要是并發連接太多了,就只能多創建線程。 但是線程太多也有問題,每個線程都會占用內存空間,數量多了系統受不了,線程之間的切換是非常要命。 所以非阻塞的方式比較好,讓一個線程管理成百上千個socket連接,就像管理多個文件一樣,不用做線程的切換。 因為在某一個時刻,不是每個socket都有數據讀寫,很多時候都是空閑的,完全可以用輪詢的方式來查看哪些socket可以讀寫,進行操作。 不過因為Stream,Reader用得太多了,不能輕舉妄動,可以設計一套新的API,叫Java NIO 也就是non-blocking IO 里面有幾個關鍵概念: * Channel:可以和原來的Steam類比,就是通過Channel讀寫數據,是非阻塞的,一個socket也是channel的一種。 * Buffer:通過Channel讀寫的數據都在Buffer,有于Buffer不是流,讀到Buffer的尾部還可以從頭讀。 * Selector:和Channel配合使用,Channel可以把自己注冊到Selector里面,告訴Selector要監聽XXX事件,這是一個線程可以管理多個 Channel的關鍵 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180823093309.png?picgo) 在一個無限循環中讓一個線程處理多個連接 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180823093347.png?picgo)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看