java NIO buffer原始碼分析

2021-08-14 10:27:51 字數 2207 閱讀 3300

buffer是個抽象類,被各個原生資料型別的buffer繼承,nio中channel是通過buffer進行資料讀寫操作的

buffer是雙向操作,既可以讀也可以寫,實現buffer讀寫轉化功能的,主要是buffer當中的各個屬性字段

執行緒不安全

這幾個字段之間的大小關係是mark<=position<=limit<=capacity

如何理解這幾個字段具體的含義

比如在初始化乙個長度為10的buffer之後,其capacity已經固定了,就是10,此時limit也可以是10,position當前並沒有往陣列中新增元素,position的索引就是0

buffer.put()新增兩個元素之後

capacity的值還是10,(永久不變)

position下乙個需要寫的索引就是2

此時limit還是等於10,如果需要將已經寫入的元素讀取出來,也就是由原來的寫入,變成讀,需要buffer.filp()

這時候position=0, limit=2, capacity=10 

進行元素讀取,直到position=2, limit =2 ,capacity=10 不能繼續再讀下去

當把所有的元素都讀取完之後,想要繼續寫入,再次執行buffer.flip()

position=0 ,limit =2 ,capacity=10 ,從0開始寫入 

* 

@return

this buffer

*/public finalbuffer flip()

這個就是原始碼中執行flip方法的操作,limit會記錄當前讀或者寫的索引最大值,position從0開始讀取,只到position=limit時,讀取或者寫入結束 

使用nio讀取檔案內容時容易出現的乙個問題

public static voidmain(string args)throwsexception

bytebuffer.flip();

fileoutputchannel.write(bytebuffer);

}}

這裡如果while迴圈中沒有bytebuffer.clear() output.txt檔案會一直不斷地增加,程式處於死迴圈當中 

原因在於:

第一次進入迴圈

step1: position=0, limit=capacity,當寫入一定資料之後,(假設有5個位元組)

position=5,limit=1024,capacity=1024

flip方法後

position=0,limit=5,capacity=1024,

將所有的資料讀取完之後,position=5,limit=5,capacity=1024

第二次次進入迴圈:

read=0

flip方法之後

position=0,limit=5,capacity=1024

陣列元素並未被清空,所以會一直讀取第一次寫入進去的位元組,程式進入死迴圈

buffer中幾個方法

clear() 是清空,重新開始寫入資料,campact是將未讀完的資料,拷貝一部分,儲存,然後繼續寫入資料,會更加浪費記憶體,clear不能讀取到之前寫入的資料

在bytebuffer, slice()方法是將當前bytebuffer的屬性拿過去,直接使用,陣列使用的是同乙個底層陣列,所以不管是之前的bytebuffer還是slice()方法返回的bytebuffer,對陣列的操作,兩個buffer都會有影響

bytebuffer scattering,gathering

scattering: channel可以讀取內容到乙個buffer陣列當中,按照資料順序,會在第乙個寫滿之後,寫入下乙個

gathering: 將多個buffer的內容寫入到channel當中

什麼時候會用到scattering和gathering?

在使用自動義網路協議是,header,body可能是不同的內容,這個時候,可以使用兩個不同長度的資料,來進行傳遞資料,而不需要使用特殊字元來進行分割,或者是擷取固定長度的buffer

AbstractCollection原始碼分析

abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...

ThreadPoolExecutor原始碼閱讀

執行緒池解決兩個問題 一是復用執行緒,減少建立銷毀執行緒帶來系統開銷 二是限定系統資源使用邊界,避免大量執行緒消耗盡系統記憶體 適用於互不依賴,執行時間短,不需要對執行緒控制操作的執行緒 新增任務時,1.若執行緒數量小於corepoolsize,則新增執行緒執行任務 2.若執行緒數量大於等於core...

OrangePi One Android 原始碼編譯

一 系統環境搭建參照 二 lichee原始碼編譯 1.檢視help build.sh h2.配置核心 cd linux 3.4 make arch arm menuconfig 進入配置頁面,上下移動列表,空格是選擇列表,左右移動選擇退出選項 3.首次編譯執行清除 在 lichee linux3.4...