1. 程式人生 > >java阻塞和NIO概念詳解

java阻塞和NIO概念詳解

 java阻塞非阻塞

  阻塞與非阻塞IO

  JAVA IO的各種流是阻塞的,這意味著,當一個執行緒呼叫read()或write()時,該執行緒被阻塞,直到有一些資料被讀取,或資料完全寫入。

  該執行緒在此期間不能再幹任何事情了。

  阻塞式網路 IO 的特點:多執行緒處理多個連線。每個執行緒擁有自己的棧空間並且佔用一些 CPU 時間。每個執行緒遇到外部未準備好的時候,都會阻塞掉。

  阻塞的結果就是會帶來大量的程序上下文切換。且大部分程序上下文切換可能是無意義的。比如假設一個執行緒監聽一個埠,一天只會有幾次請求進來,

  但是該 cpu 不得不為該執行緒不斷做上下文切換嘗試,大部分的切換以阻塞告終。

  一輛從 A 開往 B 的公共汽車上,路上有很多點可能會有人下車。司機不知道哪些點會有哪些人會下車,對於需要下車的人,如何處理更好?

  1. 司機過程中定時詢問每個乘客是否到達目的地,若有人說到了,那麼司機停車,乘客下車。 ( 類似阻塞式 )

  2. 每個人告訴售票員自己的目的地,然後睡覺,司機只和售票員互動,到了某個點由售票員通知乘客下車。 ( 類似非阻塞 )

  很顯然,每個人要到達某個目的地可以認為是一個執行緒,司機可以認為是 CPU 。在阻塞式裡面,每個執行緒需要不斷的輪詢,上下文切換,以達到找到目的地的結果。

  而在非阻塞方式裡,每個乘客 ( 執行緒 ) 都在睡覺 ( 休眠 ) ,只在真正外部環境準備好了才喚醒,這樣的喚醒肯定不會阻塞。

  非阻塞的原理

  把整個過程切換成小的任務,通過任務間協作完成。

  由一個專門的執行緒來處理所有的 IO 事件,並負責分發。

  事件驅動機制:事件到的時候觸發,而不是同步的去監視事件。

  執行緒通訊:執行緒之間通過 wait,notify 等方式通訊。保證每次上下文切換都是有意義的。減少無謂的程序切換。

  簡單的說:建立專門的執行緒來處理所有IO事件,並負責分發。(就是售票員,司機只和售票員互動,司機CPU)

  使用wait() notify()來進行執行緒的切換,保證每次上下文切換都是有意義的。