1. 程式人生 > >Java NIO入門與詳解

Java NIO入門與詳解

nio 是 New I/O 的簡稱,屬於當時 jdk1.4 提供的新 api。如今 jdk 版本已經到 1.8 了,新 IO 這個稱謂有點不合適了,nio 還有一個更合適的叫法——非阻塞(non-blocking)IO。

1. nio與io對比

1.1 檔案流與檔案塊的比較
原來的 I/O 庫(在 java.io.*中) 與 NIO 最重要的區別是資料打包和傳輸的方式。原來的 I/O 以流的方式處理資料,經常為了處理個別字節或字元,就要執行好幾個物件層的方法呼叫。而 NIO 以塊的方式處理資料。

面向流 的 I/O 系統一次一個位元組地處理資料。一個輸入流產生一個位元組的資料,一個輸出流消費一個位元組的資料。為流式資料建立過濾器非常容易。連結幾個過濾器,以便每個過濾器只負責單個複雜處理機制的一部分,這樣也是相對簡單的。不利的一面是,面向流的 I/O 通常相當慢。

一個 面向塊 的 I/O 系統以塊的形式處理資料。每一個操作都在一步中產生或者消費一個數據塊。按塊處理資料比按(流式的)位元組處理資料要快得多。但是面向塊的 I/O 缺少一些面向流的 I/O 所具有的優雅性和簡單性。

1.2 整合的 檔案I/O
在 JDK 1.4 中原來的 I/O 包和 NIO 已經很好地集成了。 java.io.* 已經以 NIO 為基礎重新實現了,所以現在它可以利用 NIO 的一些特性。例如, java.io.* 包中的一些類包含以塊的形式讀寫資料的方法,這使得即使在更面向流的系統中,處理速度也會更快。

也可以用 NIO 庫實現標準 I/O 功能。例如,可以容易地使用塊 I/O 一次一個位元組地移動資料。NIO 還提供了原 I/O 包中所沒有的許多好處。

1.3 為什麼要使用 NIO?(主要是網路I/O)
I/O的終極目標是效率,而效率離不開底層作業系統和檔案系統的特性支援。這些特性包括:檔案鎖定、非阻塞I/O、就緒性選擇、和記憶體對映。當今作業系統大都支援這些特性,而Java傳統I/O機制並沒有模擬這些通用的I/O服務。

NIO 的建立目的是為了讓 Java 程式設計師可以實現高速 I/O 而無需編寫自定義的本機程式碼。NIO 將最耗時的 I/O 操作(即填充和提取緩衝區)轉移回作業系統,因而可以極大地提高速度。

通常一次緩衝區操作是這樣的:某個程序需要進行I/O操作,它執行了一次讀(read)或者寫(write)的系統呼叫,向底層作業系統發出了請求,作業系統會按要求把資料緩衝區填滿或者排幹。

對於檔案I/O,整合的 I/O提供了對於NIO特性的支援。 企業級應用軟體中涉及I/O的部分多半是讀寫檔案的功能性需求,很少有在併發上的要求,那麼JavaIO包已經很勝任了。

對於網路I/O,傳統的阻塞式I/O,一個執行緒對應一個連線,採用執行緒池的模式在大部分場景下簡單高效。當連線數茫茫多時,並且資料的移動非常頻繁,NIO無疑是更好的選擇。

2. I/O相關概念整理

2.1 DMA
DMA(Direct Memory Access,直接記憶體存取) 是所有現代電腦的重要特色,在DMA控制器和記憶體之間傳輸資料的時候CPU是空閒的。

在dma傳輸資料的過程中,要求源實體地址和目標實體地址必須是連續的。但在有的計算機體系中,如IA,連續的儲存器地址在物理上不一定是連續的,則dma傳輸要分成多次完成。如果傳輸完一塊物理連續的資料後發起一次中斷,同時主機進行下一塊物理連續的傳輸,則這種方式即為block dma方式。scatter/gather方式則不同,它是用一個連結串列描述物理不連續的儲存器,然後把連結串列首地址告訴dma master。dma master傳輸完一塊物理連續的資料後,就不用再發中斷了,而是根據連結串列傳輸下一塊物理連續的資料,最後發起一次中斷。

很顯然scatter/gather方式比block dma方式效率高。

2.2 核心空間和使用者空間
使用者空間是常規程序所在區域。JVM就是常規程序,駐守於使用者空間。使用者空間是非特權區域:比如,在該區域執行的程式碼就不能直接訪問硬體裝置。核心空間是作業系統所在區域。核心程式碼有特別的權力:它能與裝置控制器通訊,控制著使用者區域程序的執行狀態,等等。最重要的是,所有I/O都直接或間接通過核空間。

當程序請求I/O操作的時候,它執行一個系統呼叫將控制權移交給核心。當核心以這種方式被呼叫,它隨即採取任何必要步驟,找到程序所需資料,並把資料傳送到使用者空間內的指定緩衝區。核心試圖對資料進行快取記憶體或預讀取,因此程序所需資料可能已經在核心空間裡了。如果是這樣,該資料只需簡單地拷貝出來即可。如果資料不在核心空間,則程序被掛起,核心著手把資料讀進記憶體。

為什麼不直接讓磁碟控制器把資料送到使用者空間的緩衝區呢?這樣做有幾個問題。首先,硬體通常不能直接訪問使用者空間 (硬體裝置通常不能直接使用虛擬記憶體地址) 。其次,像磁碟這樣基於塊儲存的硬體裝置操作的是固定大小的資料塊,而使用者程序請求的可能是任意大小的或非對齊的資料塊。在資料往來於使用者空間與儲存裝置的過程中,核心負責資料的分解、再組合工作,因此充當著中間人的角色。

2.3 虛擬記憶體
所有現代作業系統都使用虛擬記憶體。虛擬記憶體意為使用虛假(或虛擬)地址取代物理(硬體
RAM)記憶體地址。這樣做好處頗多,總結起來可分為兩大類:

  1. 一個以上的虛擬地址可指向同一個實體記憶體地址。
  2. 虛擬記憶體空間可大於實際可用的硬體記憶體。

裝置控制器不能通過DMA直接儲存到使用者空間,但通過利用上面提到的第一項,則可以達到相同效果。把核心空間地址與使用者空間的虛擬地址對映到同一個實體地址,這樣,DMA硬體(只能訪問實體記憶體地址)就可以填充對核心與使用者空間程序同時可見的緩衝區。但前提條件是,核心與使用者緩衝區必須使用相同的頁對齊,緩衝區的大小還必須是磁碟控制器塊大小(通常為512 位元組磁碟扇區)的倍數。作業系統把記憶體地址空間劃分為頁,即固定大小的位元組組。記憶體頁的大小總是磁碟塊大小的倍數,通常為2次冪(這樣可簡化定址操作)。典型的記憶體頁為1,024、2,048和4,096位元組。

現代作業系統的分頁技術

2.4 分頁技術
現代CPU包含一個稱為記憶體管理單元(MMU)的子系統,邏輯上位於CPU與實體記憶體之間。
該裝置包含虛擬地址向實體記憶體地址轉換時所需對映資訊。當CPU引用某記憶體地址時,MMU負責
確定該地址所在頁(往往通過對地址值進行移位或遮蔽位操作實現),並將虛擬頁號轉換為物理頁
號(這一步由硬體完成,速度極快)。如果當前不存在與該虛擬頁形成有效對映的實體記憶體頁,
MMU會向CPU提交一個頁錯誤。

頁錯誤隨即產生一個系統呼叫,把控制權移交給核心,附帶導致錯誤的虛擬地址資訊,然後核心採取步驟驗證頁的有效性。核心會安排頁面調入操作,把缺失的頁內容讀回實體記憶體。這往往導致別的頁被移出實體記憶體,好給新來的頁讓地方。在這種情況下,如果待移出的頁已經被碰過了(自建立或上次頁面調入以來,內容已發生改變),還必須首先執行頁面調出,把頁內容拷貝到磁碟上的分頁區。

如果所要求的地址不是有效的虛擬記憶體地址(不屬於正在執行的程序的任何一個記憶體段),則該頁不能通過驗證,段錯誤隨即產生。於是,控制權轉交給核心的另一部分,通常導致的結果就是程序被強令關閉。一旦出錯的頁通過了驗證,MMU隨即更新,建立新的虛擬到物理的對映(如有必要,中斷被移出頁的對映),使用者程序得以繼續。造成頁錯誤的使用者程序對此不會有絲毫察覺,一切都在不知不覺中進行。

2.5 面向塊(檔案)的I/O和流I/O

檔案I/O屬檔案系統範疇,檔案系統與磁碟迥然不同。磁碟把資料存在扇區上,通常一個扇區512 位元組。磁碟屬硬體裝置,對何謂檔案一無所知,它只是提供了一系列資料存取視窗。在這點上,磁碟扇區與記憶體頁頗有相似之處:都是統一大小,都可作為大的陣列被訪問。

檔案系統是更高層次的抽象,是安排、解釋磁碟(或其他隨機存取塊裝置)資料的一種獨特方
式。您所寫程式碼幾乎無一例外地要與檔案系統打交道,而不是直接與磁碟打交道。是檔案系統定義
了檔名、路徑、檔案、檔案屬性等抽象概念。
檔案系統把一連串大小一致的資料塊組織到一起。有些塊儲存元資訊,如空閒塊、目錄、索引
等的對映,有些包含檔案資料。單個檔案的元資訊描述了哪些塊包含檔案資料、資料在哪裡結束、
最後一次更新是什麼時候,等等。

當用戶程序請求讀取檔案資料時,檔案系統需要確定資料具體在磁碟什麼位置,然後著手把相
關磁碟扇區讀進記憶體。老式的作業系統往往直接向磁碟驅動器釋出命令,要求其讀取所需磁碟扇
區。而採用分頁技術的現代作業系統則利用請求頁面排程取得所需資料。

採用分頁技術的作業系統執行I/O的全過程可總結為以下幾步:
• 確定請求的資料分佈在檔案系統的哪些頁(磁碟扇區組)。磁碟上的檔案內容和元數
據可能跨越多個檔案系統頁,而且這些頁可能也不連續。
• 在核心空間分配足夠數量的記憶體頁,以容納得到確定的檔案系統頁。
• 在記憶體頁與磁碟上的檔案系統頁之間建立對映。
• 為每一個記憶體頁產生頁錯誤。
• 虛擬記憶體系統俘獲頁錯誤,安排頁面調入,從磁碟上讀取頁內容,使頁有效。
• 一旦頁面調入操作完成,檔案系統即對原始資料進行解析,取得所需檔案內容或屬性
資訊。

大多數作業系統假設程序會繼續讀取檔案剩餘部分,因而會預讀額外的檔案系統頁。如果記憶體
爭用情況不嚴重,這些檔案系統頁可能在相當長的時間內繼續有效。這樣的話,當稍後該檔案又被
相同或不同的程序再次開啟,可能根本無需訪問磁碟。這種情況您可能也碰到過:當重複執行類似
的操作,如在幾個檔案中進行字串檢索,第二遍執行得似乎快多了。

類似的步驟在寫檔案資料時也會採用。這時,檔案內容的改變(通過write( ))將導致檔案系統
頁變髒,隨後通過頁面調出,與磁碟上的檔案內容保持同步。檔案的建立方式是,先把檔案對映到
空閒檔案系統頁,在隨後的寫操作中,再將檔案系統頁重新整理到磁碟。

並非所有I/O都是面向塊的,也有流I/O,其原理模仿了通道。I/O位元組流必須順序存取,常見的例子有TTY(控制檯)裝置、印表機埠和網路連線。

流的傳輸一般(也不必然如此)比塊裝置慢,經常用於間歇性輸入。多數作業系統允許把流置於非阻塞模式,這樣,程序可以檢視流上是否有輸入,即便當時沒有也不影響它幹別的。這樣一種能力使得程序可以在有輸入的時候進行處理,輸入流閒置的時候執行其他功能。

比非阻塞模式再進一步,就是就緒性選擇。就緒性選擇與非阻塞模式類似(常常就是建立在非阻塞模式之上),但是把檢視流是否就緒的任務交給了作業系統。作業系統受命檢視一系列流,並提醒程序哪些流已經就緒。這樣,僅僅憑藉作業系統返回的就緒資訊,程序就可以使用相同程式碼和單一執行緒,實現多活動流的多路傳輸。這一技術廣泛用於網路伺服器領域,用來處理數量龐大的網路連線。就緒性選擇在大容量縮放方面是必不可少的。

2.6 記憶體對映檔案
記憶體對映I/O使用檔案系統建立從使用者空間直到可用檔案系統頁的虛擬記憶體對映。這樣做有幾
個好處:
• 使用者程序把檔案資料當作記憶體,所以無需釋出read( )或write( )系統呼叫。
• 當用戶程序碰觸到對映記憶體空間,頁錯誤會自動產生,從而將檔案資料從磁碟讀進記憶體。如果使用者修改了對映記憶體空間,相關頁會自動標記為髒,隨後重新整理到磁碟,檔案得到更新。
• 作業系統的虛擬記憶體子系統會對頁進行智慧快取記憶體,自動根據系統負載進行記憶體管理。
• 資料總是按頁對齊的,無需執行緩衝區拷貝。
• 大型檔案使用對映,無需耗費大量記憶體,即可進行資料拷貝。

2.7 檔案鎖定
檔案鎖定機制允許一個程序阻止其他程序存取某檔案,或限制其存取方式。通常的用途是控制共享資訊的更新方式,或用於事務隔離。在控制多個實體並行訪問共同資源方面,檔案鎖定是必不可少的。資料庫等複雜應用嚴重信賴於檔案鎖定。

“檔案鎖定”從字面上看有鎖定整個檔案的意思(通常的確是那樣),但鎖定往往可以發生在更為細微的層面,鎖定區域往往可以細緻到單個位元組。鎖定與特定檔案相關,開始於檔案的某個特定位元組地址,包含特定數量的連續位元組。這對於協調多個程序互不影響地訪問檔案不同區域,是至關重要的。

檔案鎖定有兩種方式:共享的和獨佔的。多個共享鎖可同時對同一檔案區域發生作用;獨佔鎖則不同,它要求相關區域不能有其他鎖定在起作用。

3. 緩衝區

通道 和 緩衝區 是 NIO 中的核心物件,幾乎在每一個 I/O 操作中都要使用它們。

通道是對原 I/O 包中的流的模擬。到任何目的地(或來自任何地方)的所有資料都必須通過一個 Channel 物件。一個 Buffer 實質上是一個容器物件。傳送給一個通道的所有物件都必須首先放到緩衝區中;同樣地,從通道中讀取的任何資料都要讀到緩衝區中。

Buffer 是一個物件, 它包含一些要寫入或者剛讀出的資料。 在 NIO 中加入 Buffer 物件,體現了新庫與原 I/O 的一個重要區別。在面向流的 I/O 中,您將資料直接寫入或者將資料直接讀到 Stream 物件中。

在 NIO 庫中,所有資料都是用緩衝區處理的。在讀取資料時,它是直接讀到緩衝區中的。在寫入資料時,它是寫入到緩衝區中的。任何時候訪問 NIO 中的資料,您都是將它放到緩衝區中。

緩衝區實質上是一個數組。通常它是一個位元組陣列,但是也可以使用其他種類的陣列。但是一個緩衝區不僅僅 是一個數組。緩衝區提供了對資料的結構化訪問,而且還可以跟蹤系統的讀/寫程序。

最常用的緩衝區型別是 ByteBuffer。一個 ByteBuffer 可以在其底層位元組陣列上進行 get/set 操作(即位元組的獲取和設定)。

ByteBuffer 不是 NIO 中唯一的緩衝區型別。事實上,對於每個非布林原始資料型別都有一種緩衝區類

ByteBuffer
CharBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer

每一個 Buffer 類都是 Buffer 介面的一個例項。 除了 ByteBuffer,每一個 Buffer 類都有完全一樣的操作,只是它們所處理的資料型別不一樣。因為大多數標準 I/O 操作都使用 ByteBuffer,所以它具有所有共享的緩衝區操作以及一些特有的操作。

3.1 緩衝區基礎
所有的緩衝區都具有四個屬性來提供關於其所包含的資料元素的資訊。它們是:

容量(Capacity)

緩衝區能夠容納的資料元素的最大數量。這一容量在緩衝區建立時被設定,並且永遠不能
被改變。

limit 決不能大於 capacity。

上界(Limit)

緩衝區的第一個不能被讀或寫的元素limit 變量表明還有多少資料需要取出(在從緩衝區寫入通道時),或者還有多少空間可以放入資料(在從通道讀入緩衝區時)。

position 總是小於或者等於 limit。。或者說,緩衝區中現存元素的計數。

位置(Position)

下一個要被讀或寫的元素的索引。位置會自動由相應的get()和put( )方法更新。

您可以回想一下,緩衝區實際上就是美化了的陣列。在從通道讀取時,您將所讀取的資料放到底層的陣列中。 position 變數跟蹤已經寫了多少資料。更準確地說,它指定了下一個位元組將放到陣列的哪一個元素中。因此,如果您從通道中讀三個位元組到緩衝區中,那麼緩衝區的 position 將會設定為3,指向陣列中第四個元素。

同樣,在寫入通道時,您是從緩衝區中獲取資料。 position 值跟蹤從緩衝區中獲取了多少資料。更準確地說,它指定下一個位元組來自陣列的哪一個元素。因此如果從緩衝區寫了5個位元組到通道中,那麼緩衝區的 position 將被設定為5,指向陣列的第六個元素。

標記(Mark)

一個備忘位置。呼叫mark( )來設定mark= postion。呼叫reset( )設定position=
mark。標記在設定前是未定義的(undefined)。

這四個屬性之間總是遵循以下關係:0 <= mark <= position <= limit <= capacity

3.2 緩衝區API

    package java.nio; 
    /**
     *關於這個API有一點要注意的是,像clear()這類方法,您通常應當返回void,而不
     *是Buffer引用。這些方法將引用返回到它們在(this)上被引用的物件。這是一個允許級
     *聯呼叫的類設計方法。級聯呼叫允許這種型別的程式碼:
     *
     *對於API還要注意的一點是isReadOnly()方法。所有的緩衝區都是可讀的,但並非所
     *有都可寫。
     */
    public abstract class Buffer { 
        public final int capacity();
        public final int position();
        public final Buffer position(int newPosition);
        public final int limit();
        public final Buffer limit(int newLimit); 
        //緩衝區的標記在mark( )方法被呼叫之前是未定義的(值為-1)。一些緩衝區方法會拋棄已經設定的標記(rewind(),clear(),以及flip()總是拋棄標記)。如果新設定的值比當前的標記小,呼叫limit()或position()帶有索引引數的版本會拋棄標記。
        public final Buffer mark();
        //reset( )方法將位置設為當前的標記值。
        public final Buffer reset();
        //將上界設為容量的值,並把位置設回0,這使得緩衝區可以被重新填入。
        public final Buffer clear();
        //翻轉 相當於limit(buffer.position()).position(0)
        public final Buffer flip();
        //與flip()相似,但不影響上界屬性。它只是將位置值設回0。您可以使用rewind()後退,重讀已經被翻轉的緩衝區中的資料。
        public final Buffer rewind();
        public final int remaining();
        public final boolean hasRemaining();
        public abstract  boolean isReadOnly(); 
    }

上面所列出的的Buffer API並沒有包括get()或put()方法。每一個Buffer類都有這兩個方法,但它們所採用的引數型別,以及它們返回的資料型別,對每個子類來說都是唯一的,所以它們不能在頂層Buffer類中被抽象地宣告。

Get和Put可以是相對的或者是絕對的。當相對方法被呼叫時,位置在返回時前進一。如果位置前進過多,相對運算就會丟擲異常。絕對存取需要傳遞索引引數,方法呼叫不會影響緩衝區的位置屬性,但是如果您所提供的索引超出範圍(負數或不小於上界),也將丟擲IndexOutOfBoundsException異常。

3.3 位元組緩衝區
位元組是作業系統及其I/O裝置使用的基本資料型別。當在JVM和作業系統間傳遞資料時,將其他的資料型別拆分成構成它們的位元組是十分必要的。系統層次的I/O面向位元組的性質可以在整個緩衝區的設計以及它們互相配合的服務中感受到。

    package java.nio; 
    public abstract class ByteBuffer extends Buffer implements Comparable 
    { 
        public static ByteBuffer allocate (int capacity); 
        public static ByteBuffer allocateDirect (int capacity); 
        public abstract  boolean isDirect(); 
        public static ByteBuffer wrap (byte[] array, int offset, int length); 
        public static ByteBuffer wrap (byte[] array); 
        public abstract ByteBuffer duplicate(); 
        public abstract  ByteBuffer asReadOnlyBuffer(); 
        public abstract  ByteBuffer slice(); 
        public final boolean hasArray(); 
        public final byte[] array(); 
        public final int arrayOffset(); 
        public abstract  byte get(); 
        public abstract byte get (int index); 
        public ByteBuffer get (byte[] dst, int offset, int length); 
        public abstract ByteBuffer put (byte b); 
        public abstract ByteBuffer put (int index, byte b); 
        public ByteBuffer put (ByteBuffer src); 
        public ByteBuffer put (byte[] src, int offset, int length); 
        public final ByteBuffer put (byte[] src); 
        public final ByteOrder order(); 
        public final ByteBuffer order (ByteOrder bo); 
        public abstract  CharBuffer asCharBuffer(); 
        public abstract ShortBuffer asShortBuffer(); 
        public abstract  IntBuffer asIntBuffer(); 
        public abstract LongBuffer asLongBuffer(); 
        public abstract  FloatBuffer asFloatBuffer(); 
        public abstract DoubleBuffer asDoubleBuffer(); 
        public abstract char getChar(); 
        public abstract char getChar (int index); 
        public abstract ByteBuffer 
            
           

相關推薦

Java NIO入門

nio 是 New I/O 的簡稱,屬於當時 jdk1.4 提供的新 api。如今 jdk 版本已經到 1.8 了,新 IO 這個稱謂有點不合適了,nio 還有一個更合適的叫法——非阻塞(non-blocking)IO。 1. nio與io對比 1

Hibernate - 檢索策略入門

檢索資料時的 2 個問題: 不浪費記憶體:當 Hibernate 從資料庫中載入 Customer 物件時, 如果同時載入所有關聯的 Order 物件, 而程式實際上僅僅需要訪問 Customer 物件, 那麼這些關聯的 Order 物件就白白浪費了許多記憶體。 更高的

Java異常處理問題合集

Java異常處理與詳解  作者:華 日期:2018年5月30日 一次考試考到Java自定義異常,沒有做出來,只是簡單地瞭解了一下,為了鞏固知識,就從各大網站總結了關於Java異常的處理解釋來加深自己的印象。(全部文字雖有雷同但都是親自手打無複製) Java異常的意義: 異

java NIO入門

在開始之前關於本教程新的輸入/輸出 (NIO) 庫是在 JDK 1.4 中引入的。NIO 彌補了原來的 I/O 的不足,它在標準 Java 程式碼中提供了高速的、面向塊的 I/O。通過定義包含資料的類,以及通過以塊的形式處理這些資料,NIO 不用使用本機程式碼就可以利用低階優

PHPJava集成開發(一)

new 編程語言 到你 其中 web-inf request 測試 add 輸入 很久以前,有人從www上看到看到天空上一個很亮的亮點,它就是Java語言,與此同時,在另一個地方一位夢想家也看到了一個亮點,它就是PHP。 時間一天天過去,這兩個亮點也變得越來越亮,很快,它

數據結構 - 從二叉搜索樹說到AVL樹(一)之二叉搜索樹的操作Java

判斷 right 不為 exist avl 輸入 位置 bubuko get   二叉搜索樹(Binary Search Tree),簡稱BST,顧名思義,一顆可以用於搜索的二叉樹。BST在數據結構中占有很重要的地位,一些高級樹結構都是其的變種,例如AVL樹、紅黑樹等,因此

java基礎原來這麼容易入門

8種基本型別 int 整形 long 長整形 short 段整形 double 雙精度 float 單精度 char 字元型別 boolean 布林型別 byte 位元組型別 2 1995年由sun公司開發的 2009年 由oracle收購 3 2種技術平臺 java SE:標準版 java

java 的位運算子例項 ------(&) 、或( |) 、非( ~) 、異或( ^)

位運算子主要針對二進位制,它包括了:“與”、“非”、“或”、“異或”。從表面上看似乎有點像邏輯運算子,但邏輯運算子是針對兩個關係運算符來進行邏輯運算,而位運算子主要針對兩個二進位制數的位進行邏輯運算。下面詳細介紹每個位運算子。   1.與運算子 與運算子用符號“&”表示,

Caffe入門例項 人工智慧框架

Caffe的幾個重要檔案 用了這麼久Caffe都沒好好寫過一篇新手入門的部落格,最近應實驗室小師妹要求,打算寫一篇簡單、快熟入門的科普文。  利用Caffe進行深度神經網路訓練第一步需要搞懂幾個重要檔案: solver.prototxt train_val.proto

Java併發(十二):CAS Unsafe Atomic 說一說Java的Unsafe類 說一說Java的Unsafe類 Java中Unsafe類 UnsafeCAS

一、Unsafe Java無法直接訪問底層作業系統,而是通過本地(native)方法來訪問。不過儘管如此,JVM還是開了一個後門,JDK中有一個類Unsafe,它提供了硬體級別的原子操作。 這個類儘管裡面的方法都是public的,但是並沒有辦法使用它們,JDK API文件也沒有提供任何關於這個類的方法的解

【小家javaJava定時任務ScheduledThreadPoolExecutor以及Timer、TimerTask的區別

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

Java解析HTML之HTMLParser使用

 出處: http://free0007.iteye.com/blog/1131163 HTMLParser具有小巧,快速的優點,缺點是相關文件比較少(英文的也少),很多功能需要自己摸索。對於初學者還是要費一些功夫的,而一旦上手以後,會發現

Java 高併發程式設計:多執行緒架構設計

內容簡介 本書主要包含四個部分: 部分主要闡述 Thread 的基礎知識,詳細介紹執行緒的 API 使用、執行緒安全、執行緒間資料通訊,以及如何保護共享資源等內容,它是深入學習多執行緒內容的基礎。 第二部分引入了 ClassLoader,這是因為 ClassLoader 與執行緒不無關係

java環境變數 的配置(全網最詳細教程)

筆者這學期開始學習java課程,學習java開發首先需要配置java執行環境變數。雖然上課老師也講了如何配置java環境變數,可是筆者的同學還是有好多都不會配置,所以筆者最近配置了特別多次java環境變數。如下筆者詳細解釋從JDK安裝到環境變數的裝配。 目錄

Java七大設計原則運用

開心一笑 【婚禮上,氣氛正高著,主持人問新郎:”你會不會愛新娘一輩子?新郎興高采烈的喊:”會”。主持人:”你會不會在新娘容顏憔悴,疾病纏身的時候離開她? 猴急的新郎興高采烈的喊:”會”!】 課程介紹 Java七大設計原則在工作中是非常重要的

java執行緒池的使用

正在執行task 0 執行緒池中執行緒數目:1,佇列中等待執行的任務數目:0,已執行玩別的任務數目:0 執行緒池中執行緒數目:2,佇列中等待執行的任務數目:0,已執行玩別的任務數目:0 正在執行task 1 執行緒池中執行緒數目:3,佇列中等待執行的任務數目:0,已執行玩別的任務數目:0 正在執行task 2

Vagrant使用入門技巧

Vagrant是一個基於Ruby的工具,用於建立和部署虛擬化開發環境。它 使用Oracle的開源VirtualBox虛擬化系統,使用 Chef建立自動化虛擬環境了,安裝方法是非常的簡單的,下面一起來看看Vagrant使用與入門技巧. 1.1 專案初始化 Vagran

Java八大基本型別包裝類

java八大基本型別: 整型: byte: byte資料型別是8位、有符號的,以二進位制補碼錶示的整數; 最小值是-128(-2^7); 最大值是127(2^7-1); 預設值是0; byte型別用在

Java併發——Executor框架(Executor框架結構框架成員)

一、什麼是Executor框架?我們知道執行緒池就是執行緒的集合,執行緒池集中管理執行緒,以實現執行緒的重用,降低資源消耗,提高響應速度等。執行緒用於執行非同步任務,單個的執行緒既是工作單元也是執行機制,從JDK1.5開始,為了把工作單元與執行機制分離開,Executor框架

java內外部比較器(Comparator、Comparable)使用場景

內外部比較器使用: 內部比較器:需比較的類實現介面 Comparable,使該類對外提供一個預設比較的實現 public class Test { public static void main(String[] args) {