Java 为什么是Tomcat';s非阻塞连接器是否使用阻塞插座?
我阅读了有关非阻塞I/O、java NIO和tomcat连接器的内容,查看了tomcat NIO连接器的代码,并且:Java 为什么是Tomcat';s非阻塞连接器是否使用阻塞插座?,java,tomcat,nio,Java,Tomcat,Nio,我阅读了有关非阻塞I/O、java NIO和tomcat连接器的内容,查看了tomcat NIO连接器的代码,并且: 我没有NIO方面的经验,所以有人能解释一下,当套接字被配置为阻塞时,它是如何非阻塞的吗?看起来下面这行代码是在这次提交时引入的 据我所知,NioEndpoint正在使用blocking ServerSocketChannel来阻止和等待传入连接,只有在接受该连接后,它才会以非阻塞方式处理该传入套接字通道(请参阅setSocketOptions方法) 将ServerSocketCh
我没有NIO方面的经验,所以有人能解释一下,当套接字被配置为阻塞时,它是如何非阻塞的吗?看起来下面这行代码是在这次提交时引入的 据我所知,NioEndpoint正在使用blocking ServerSocketChannel来阻止和等待传入连接,只有在接受该连接后,它才会以非阻塞方式处理该传入套接字通道(请参阅setSocketOptions方法) 将ServerSocketChannel设置为非阻塞模式的替代方法将导致作者指出的繁忙读取,即线程将不断轮询传入连接,因为非阻塞模式下的accept()可能返回null 你可以找到一些有用的解释 附言。
我假设神秘的APR代表Apache便携式运行时。从调用者的角度看是非阻塞的。API仍然需要使用阻塞(在工作线程中)或异步I/O来实际完成操作。否则,套接字将需要一个带有CPU浸泡的自旋锁
您需要查看实现的其余部分,以了解此映射是如何完成的。阅读代码后: 正在侦听传入连接的
serverSock
对象被阻塞。与其新接受的连接关联的套接字
通道对象是实现非阻塞I/O的对象
侦听传入连接的线程的Acceptor类在其run
方法中具有以下定义:
protected class Acceptor extends AbstractEndpoint.Acceptor {
@Override
public void run() {
// Loop until we receive a shutdown command
while (running) {
// Loop if endpoint is paused
while (paused && running) {
...
try {
........
SocketChannel socket = null;
try {
// Accept the next incoming connection from the server
// socket
socket = serverSock.accept();
} catch (IOException ioe) {............}
...................
// setSocketOptions() will add channel to the poller
// if successful
if (running && !paused) {
if (!setSocketOptions(socket)) {
countDownConnection();
closeSocket(socket);
}
} ....
如您所见,是setSocketOptions
方法处理新的socket
,它具有以下代码:
protected boolean setSocketOptions(SocketChannel socket) {
// Process the connection
try {
//disable blocking, APR style, we are gonna be polling it
socket.configureBlocking(false);
Socket sock = socket.socket();
socketProperties.setProperties(sock);
与用于在相应连接的端点中发送/接收数据的每个连接关联的socket
通道对象是真正实现非阻塞I/O
的对象
尽管人们总是可以将serverSock
对象accept
方法设置为非阻塞,但我认为使select
(即accept)操作非阻塞是不切实际的,不会有任何实际用途,在任何实际环境中都不会有用。我想不出任何非阻塞接受操作有用的用例。这是给我的。是否应该将其设置为false
以使其成为非阻塞,这是您的问题,对吗?您似乎没有听说过java.nio.channels.Selector。您是对的-我没有听说过。注释仍然正确,因为仍然需要映射到一些底层操作系统操作,并且在*ix实现中可能映射到sockets API select()调用@ultrajohn为选择套接字上的阻塞设置提供了更精确的理由。正如我所建议的那样,NIO似乎在每个接受会话上都有一个线程。
protected boolean setSocketOptions(SocketChannel socket) {
// Process the connection
try {
//disable blocking, APR style, we are gonna be polling it
socket.configureBlocking(false);
Socket sock = socket.socket();
socketProperties.setProperties(sock);