java之BIO與NIO圖解
java中網路通訊是通過Socket實現的,Socket分為ServerSocket與Socket兩類;ServerSocket用於服務端,可以通過accept監聽請求,監聽到請求後返回Socket,用於具體完成資料傳輸,而客戶端直接使用Socket發起請求並傳輸資料。
仍然存在的缺點:
1.每個Socket接收到,都會建立一個執行緒,執行緒的競爭、切換上下文影響效能;
2.每個執行緒都會佔用棧空間和CPU資源;
3.並不是每個socket都進行IO操作,無意義的執行緒處理;
從JDK1.4開始,java增加了新的io模式的nio,nio在底層採用了新的處理方式,極大的提高了IO的效率,而Socket也屬於io的一種,nio提供了相應的工具:ServerSocketChannel和SocketChannel,與原來的相對應;
總結一下NioSocket服務端的處理過程:
1.建立ServerSocketChannel並設定相應引數;
2.建立Selector並註冊到ServerSocketChannel上;
3.呼叫Selector的select方法等待請求;
4.Selector接收到請求後使用selectKeys返回SelectKey的集合;
5.使用SelecttionKey獲取到Channel、Selctor和操作型別並進行具體操作;
優化:
一銀行辦理業務的升級為例:
1.單視窗辦理業務-->多視窗辦理業務;
2.客戶排隊模式-->銀行取號機登記註冊式(取到號後可以去幹其他事情,聽到叫號再去辦理)
3.告訴業務員一項業務,辦理一項-->一次性提交資料與資訊,全部一次辦理(如果是複雜業務,則交給後臺其他業務員辦理,當前業務員繼續處理該視窗負責業務);
以下就是NIO的具體優化(與上面場景可對應)
1.Selector通過其靜態工廠方法open建立後註冊到靜態工廠方法建立的ServerSocketChannel上,降低了連線開閉資源的消耗(NIO多路複用);
2.操作分離的請求處理,避免了原accept後操作的阻塞;
3.Buffer的使用降低了原生read/write的阻塞;
其中用到了Buffer,在此簡介一下:
Buffer是java.nio的一個類,其有4個屬性非常重要:
capacity :容量,最多可以儲存元素的數量,建立時設定,過程中不可變;
limit: 可以使用的上限,裡面有多少資料,上限就是多少;
position: 當前操作元素所在的索引位置,開始為0,隨著get與put方法自動更新;
mark: 用來暫時儲存postion的位置,可以暫時操作其他元素,然後通過reset將mark值恢復到postion,即Buffer.reset();
buffer.clear:重新初始化,limit=capacity,position=0,mark=-1;
buffer.flip():buffer每儲存一個數據,position+1,儲存完成後將最後的postion賦值給limit,然後恢復到0,這樣就可以讀取資料了(資料鎖定);