日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
沒吃透Netty緩沖區(qū),還能算得上Java老司機?

本文轉(zhuǎn)載自微信公眾號「小明菜市場」,作者小明菜市場。轉(zhuǎn)載本文請聯(lián)系小明菜市場公眾號。

前言

Java NIO 需要理解的主要有緩沖區(qū),通道,選擇器,這三個主要的部分。

基礎

用戶空間和內(nèi)核空間

操作系統(tǒng)為了提供穩(wěn)定性,把虛擬地址空間分為用戶空間和內(nèi)核空間,其中用戶進程只能操作用戶空間的內(nèi)容,而內(nèi)核空間的內(nèi)容可以操作用戶空間的內(nèi)容以及用戶空間的內(nèi)容。

I/O過程中的數(shù)據(jù)流向

假設我們需要從磁盤中的某個文件讀取數(shù)據(jù),進程發(fā)起read系統(tǒng)調(diào)用,進入內(nèi)核狀態(tài),內(nèi)核會隨即向磁盤控制硬件發(fā)出命令,要求其從磁盤讀取數(shù)據(jù),磁盤控制器把數(shù)據(jù)直接寫入到內(nèi)核緩沖區(qū)中,隨后內(nèi)核會吧數(shù)據(jù)從內(nèi)核空間的臨時緩沖區(qū)拷貝到用戶緩沖區(qū),進程再次切換回用戶態(tài)繼續(xù)執(zhí)行。總結(jié)數(shù)據(jù)流向是:磁盤 -> 內(nèi)核緩沖區(qū) -> 用戶緩沖區(qū)

內(nèi)存空間多重映射

對于虛擬地址的空間,一個以上的虛擬地址可以指向同一個物理內(nèi)存地址。如果用戶空間的虛擬地址和內(nèi)核空間的虛擬地址映射到同一個物理地址,那么這塊物理地址代表的空間就對內(nèi)核和用戶進程都可見。便可省去數(shù)據(jù)在內(nèi)核緩沖區(qū)和用戶緩沖區(qū)來回復制的開銷。

緩沖區(qū)

Java NIO 數(shù)據(jù)傳輸過程,數(shù)據(jù)先放到發(fā)送緩沖區(qū) -> 通過通道發(fā)送到接收端 -> 接受端通道接受數(shù)據(jù)并填充到接受緩沖區(qū) 所以緩沖區(qū)的作用其實是連接通道作為數(shù)據(jù)傳輸?shù)哪繕嘶蛘邅碓础?/p>

核心概念

屬性

需要理解Buffer工作機制,需要了解如下幾個屬性

  1. 容量: 緩沖區(qū)的容量,創(chuàng)建緩沖區(qū)時指定
  2. 位置: 下一個要被讀取或者寫入元素的索引
  3. 上界: 緩沖區(qū)中第一個不能被讀或者寫的位置。
  4. mark標記,一個備忘的位置

存取

緩沖區(qū)的核心就在于存取操作,buffer提供了相對位置存取和絕對位置存取兩種方式。

  1. 相對位置存?。涸诋斍暗奈恢脤懭牖蛘咦x取數(shù)據(jù),然后增加位置的值。
  2. 絕對位置存取。在指定的位置的寫入或者讀取數(shù)據(jù),不改變位置的值

代碼如下

 
 
 
 
  1. //相對位置存取
  2.  public abstract ByteBuffer put(byte b);
  3.  public abstract byte get();
  4.  //絕對位置存取
  5.  public abstract ByteBuffer put(int index, byte b);
  6.  public abstract byte get(int index);

翻轉(zhuǎn)

翻轉(zhuǎn)是 buffer的核心概念,可以理解buffer有兩種模式,寫模式和讀模式。寫模式:我們分配一個緩沖區(qū),然后直接填充數(shù)據(jù),讀模式下。我們從頭開始讀取數(shù)據(jù)。如何從寫模式切換到讀模式,翻轉(zhuǎn),翻轉(zhuǎn)的時候我們用limit記錄待讀取數(shù)據(jù)的長度,然后把位置置換為0就可以開始讀取數(shù)據(jù)了。

 
 
 
 
  1. public final Buffer flip() {
  2.    //記錄待讀取數(shù)據(jù)的長度
  3.     limit = position;
  4.    //從頭開始讀取數(shù)據(jù)
  5.     position = 0;
  6.     mark = -1;
  7.     return this;
  8. }

demo

 
 
 
 
  1. //創(chuàng)建一個緩沖區(qū) 
  2. ByteBuffer buffer = ByteBuffer.allocate(100);
  3. //寫數(shù)據(jù)
  4. for (char c : "hello".toCharArray()) {
  5.   buffer.put((byte) c);
  6. }
  7. //翻轉(zhuǎn)
  8. buffer.flip();//等價于 buffer.limit(buffer.position()).position(0);
  9. //讀數(shù)據(jù)
  10. while (buffer.hasRemaining()) {
  11.   char c = (char) buffer.get();
  12.   System.out.println(c);
  13. }

直接緩沖區(qū)

對于一般的I/O過程,數(shù)據(jù)流向是,磁盤或者網(wǎng)絡 -> 內(nèi)核臨時緩沖區(qū) -> 用戶空間緩沖區(qū)

直接緩沖區(qū)解決的是內(nèi)核空間臨時緩沖區(qū)到用戶空間緩沖區(qū)復制這一步耗費的多余。雖然直接緩沖區(qū)是I/O的最佳選擇,但是其比創(chuàng)建非直接緩沖區(qū)將會耗費更大的成本了,所以一般都是直接重復使用。

創(chuàng)建緩沖區(qū)

Buffer不能直接通過構(gòu)造函數(shù)實例化,都是通過靜態(tài)工廠方法創(chuàng)建,下為ByteBuffer的靜態(tài)工廠方法。

 
 
 
 
  1. //創(chuàng)建內(nèi)存緩沖區(qū)
  2. public static ByteBuffer allocate(int capacity);
  3. //創(chuàng)建直接緩沖區(qū)
  4. public static ByteBuffer allocateDirect(int capacity) ;
  5. public static ByteBuffer wrap(byte[] array, int offset, int length)

網(wǎng)站標題:沒吃透Netty緩沖區(qū),還能算得上Java老司機?
分享路徑:http://m.5511xx.com/article/coedoch.html