2016-04-25 102 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