Java中的NIO非阻塞模式和傳統的IO的阻塞模式線上程中的資源消耗
java中的NIO對於需要IO操作的程式來說,大大的提高了效率,但從NIO的實現模式來看(底層select的遍歷),因為其非阻塞的特性,犧牲了更多的系統資源,充分利用了硬體資源。
在java的網路程式設計中,少不了執行緒操作。那麼這兩種模式對系統的消耗情況是什麼樣子呢?下面來分享一個自己的一次優化經驗
我們的程式是SOCKET網路訪問,每秒的互動數量不小於500,除了網路狀況的要求外,程式的優化非常關鍵。
我們的程式中有3條NIO的執行緒,有20多條傳統模式的IO執行緒。我們再while迴圈裡面都沒有休眠時間來看系統消耗。
在有3條NIO(也包括了非常多的其他業務的處理執行緒),while中沒有休眠時間,CPU100%執行(CPU 2.26G 8執行緒),這個時候NIO是工作在非阻塞模式,也就是說如果沒有休眠時間,該執行緒是不會釋放CPU時間的。在while中加入了休眠1ms,CPU立馬降到 70%,基本上一個NIO無休眠執行緒消耗10%的CPU,也就是對於 單核的CPU來說80%的消耗。
還有20條的阻塞模式的執行緒(執行緒在應用級別非同步接收提交的結果),while迴圈中沒有休眠時間,因為其非阻塞模式,在IO被佔用的時候,後來進來的IO操作等待,這個過程對CPU時間進行了釋放,這樣也就是說while迴圈中雖然沒有休眠時間,但是實際上是休眠了阻塞的時間。當在同樣的硬體環境和作業系統下,啟動這20個執行緒的時候,CPU消耗18%左右
由上面的實際的例子可以看出,在進行NIO的程式設計的時候,一定要注意考慮到他的非阻塞模式,給系統的資源消耗帶來的影響。無論多快的應用需求,一定給NIO的執行緒休眠時間,如果不休眠是真正的“死迴圈”,會導致系統資源的大量消耗。
從實際我們的平臺執行的情況看,如果需要大量的基於SOCKET的網路互動,因為阻塞模式的侷限,NIO是很有必要的。JAVA中的執行緒休眠時間只能是ms級別的,也就是說NIO的操作,如果想要低的系統資源消耗,那麼就只能每秒1000次得處理。目前還沒有找到好的方法讓休眠時間更多,只要給執行緒休眠時間,CPU就不會100%執行!