日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Java NIO中的Buffer

發布時間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java NIO中的Buffer 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

  Buffer緩沖區,首先要弄明白的是,緩沖區是怎樣一個概念。它其實是緩存的一種,我們常說的緩存,包括保存在硬盤上的瀏覽器緩存,保存在內存中的緩存(比如Redis、memcached)。Buffer是把數據保存在內存中,它本質上用來保存數據的數據結構是數組,例如ByteBuffer是byte數組,IntBuffer是int數組等,對Buffer讀寫操作,其實是對該數組進行數據存放、讀取、清除操作。

  Buffer可以理解成是一個容器,可以往容器里寫入數據,也可以從容器中讀取數據,可以一個字節一個字節的讀寫,也可以多個字節讀寫,可以在寫的途中切換為讀,讀到一半又切換到寫,等等。。。

  Buffer有以下幾個屬性:

  • int mark 標記
  • int position 位置
  • int limit限制
  • int capacity緩沖區的容量,Buffer的容量是固定的,在創建Buffer對象時,制定容量大小。

  這幾個屬性,有什么作用,用在什么地方,為何設置這4個屬性。其實不用先理解,在了解reset(),flip()等方法后,就會明白這四個屬性的用處。

主要方法

mark、reset

  • mark() 在Buffer當前的位置設置標記
public final Buffer mark() {mark = position;return this;
}
  • reset() 重置Buffer當前的位置為上一次的標記
public final Buffer reset() {int m = mark;if (m < 0)throw new InvalidMarkException();position = m;return this;
}

  這兩個方法的使用場景,從Buffer讀取n個字節數據,結果讀出來的數據長度比n小(比如網絡是拆包問題),這時候會重新再讀一次,調用reset()方法。但并不是所有讀操作是從位置0開始讀,所以在reset()先設置一個標記,調用mark(),最后position = mark,就是從標記的mark位置開始讀。

clear,flip, rewind

  • clear() 清除Buffer
public final Buffer clear() {position = 0;limit = capacity;mark = -1;return this;
}
  • flip() 反轉Buffer,何謂“反轉”?在執行完寫操作之后,調用調用flip()為下次的讀操作準備。
public final Buffer flip() {limit = position;position = 0;mark = -1;return this;
}

  使用場景:在進行完寫操作后,寫入100個字節,所以當前位置position=100,為了下次讀操作,讀出來是這100個字節數據,所以limit也設為100,限制最多讀到100個字節。下次讀是從位置0開始,所以position=0。

ByteBuffer buffer = ByteBuffer.allocate(100);
String value = "zhangxh20";
buffer.put(value.getBytes());
buffer.flip();
byte [] arr = new byte[buffer.remaining()];
buffer.get(arr);
String decodeValue = new String(arr);

  看下調用flip()操作前后的對比。

  如果不做flip操作,讀到的將是position到capacity之間的錯誤內容。

  當執行flip()操作之后,它的limit被設置為position,position設置為0,capacity不變,由于讀取的內容是從position到limit之間,因此,他能夠正確讀取到之前寫入緩沖區的內容。

  • rewind() 重繞Buffer,可以發現rewind()比flip()少了個步驟limit = positon。
public final Buffer rewind() {position = 0;mark = -1;return this;
}

  使用場景:buffer.get(array),把buffer的數據復制到array數組里,會調用buffer的get()方法。get()是從position開始復制,最多limit個,所以只需positon設置為0。

其他特性

不變式

  標記、位置、限制和容量值遵守以下不變式:

  0 <= 標記 <= 位置 <= 限制 <= 容量
  新創建的緩沖區總有一個 0 位置和一個未定義的標記。初始限制可以為 0,也可以為其他值,這取決于緩沖區類型及其構建方式。一般情況下,緩沖區的初始內容是未定義的。

線程安全

  Buffer不是線程安全的,被多個線程使用時,需要加同步。

ByteBuffer

  byteBuffer字節緩沖區,即每次調用get()或者put()操作的數據最小單位是byte,理IntBuffer、LongBuffer、DoubleBuffer以此類推。例如LongBuffer put()最小的單位是8個字節的long數據。日常開發中,ByteBuffer使用的會比較多,其他類型Buffer很少使用。
  事實上ByteBuffer也可以用來表示其他類型Buffer,比如IntBuffer的get(),可以用ByteBuffer的getInt(),兩個實現效果一樣。

堆內存和直接內存

  Buffer在創建時,必須指定容量大小,還有分配內存的類型,有兩種堆內存和直接內存,直接可以理解為堆外的內存空間,區別就是,直接內存是不受GC管理

參考資料

  • 《Netty權威指南》

轉載于:https://www.cnblogs.com/zhangxh20/p/7163863.html

總結

以上是生活随笔為你收集整理的Java NIO中的Buffer的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。