2016-04-25 103 views
0

這是來自FileWatcher java 7 nio庫的代碼片段。 它是非阻塞代碼嗎?這個線程等待來自FileSystem的信號。Filewatcher是否在Java中考慮了非阻塞IO?

for (;;) { 
    // wait for key to be signaled 
    WatchKey key; 
    try { 
     key = watcher.take(); 
    } catch (InterruptedException x) { 
     return; 
    } 
} 
+0

如果它在與您所關注的進程分離的線程中運行,那麼它與其他代碼無關。線程內部的代碼示例不是非阻塞 –

+2

@ cricket_007:這不是非阻塞手段。這與IO無關。 – SLaks

+1

在這種情況下非阻塞意味着啓動I/O的用戶線程不會暫停,直到I/O完成。在較低層次上,將會有一個線程,它的任務是處理I/O中斷,並根據當前掛起的請求表找出如何處理它們。在線程處理所有當前中斷之後,它將阻塞,直到下一個I/O中斷。但是你無法訪問該線程,它與用戶代碼無關。取決於NIO如何實現該線程可以是Java或在操作系統中。 –

回答

1

Filewatcher使用EPOLL這是一個Linux系統調用。這是一種基於事件的複用機制。對於Windows,有SELECT這是做同樣的事情,但效率遠低於BSD(這是OSX的基礎),有KQUEUE

簡而言之,它會在正在等待事件發生的系統中註冊事件處理程序。隨着時間的推移,系統會查看所有排隊的事件處理程序,並查看是否有可以繼續執行的事件處理程序。如果有事件處理程序將其事件標誌設置爲true,則它將處理該事件。如果沒有事件,它將繼續循環直到找到發生的事件。

與此同時,main中的代碼繼續運行,從而爲您提供其承諾的「非阻塞」功能。

雖然ASYNC最近因爲NodeJS,Swift和其他非阻塞語言/框架的興起而變得相當流行,但這同樣也是WIN32 API的作用 - 簡而言之,它是所有事件根據。

您可以查看此link以獲得更深入的解釋。

+0

上面的代碼片段中的等待和信令過程是同步的。 「take」方法等待I/O事件,並且WatchKey的初始狀態已準備好,直到事件處理系統發出信號。同樣,WatchKey必須重置回就緒狀態。此代碼必須處於無限循環才能觀察文件夾/文件事件。爲了保存主線程,Watcher服務需要在單獨的用戶線程中創建。 – devv