我正在阅读非阻塞I / O,java NIO和tomcat连接器,查看了tomcat的NIO连接器的代码,以及found this in NioEndpoint.bind()
:
serverSock.configureBlocking(true); //mimic APR behavior
我没有NIO的经验,所以有人可以解释当套接字被配置为阻塞时它是如何非阻塞的吗?
答案 0 :(得分:2)
据我所知,NioEndpoint正在使用阻塞ServerSocketChannel来阻止和等待传入连接,并且只有在它接受后才以非阻塞方式处理这个传入套接字通道(请参阅setSocketOptions方法) )。
使ServerSocketChannel成为非阻塞的替代方法将导致作者指出忙读 - 这是一个线程将不断轮询传入连接,因为非阻塞模式下的accept()可能返回null。
您可以找到一些有用的解释here。
P.S。 我认为神秘的APR代表Apache Portable Runtime。
答案 1 :(得分:1)
阅读完代码后:
serverSock
对象正在侦听传入连接阻止。与其新接受的连接关联的socket
频道对象是实现非阻止 I / O的连接。
作为侦听传入连接的线程的Acceptor class
在其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
的{{1}}方法具有以下代码:
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
的通道对象。
虽然可以始终将non-blocking I/O
对象serverSock
方法设置为非阻塞,但我认为使accept
(即接受)操作无阻塞是不切实际的,并且会不服务于任何真正的目的,并且在任何真实的环境中都没有用。我想不出任何非阻塞接受操作有用的用例。那是给我的。
答案 2 :(得分:0)
从呼叫者的角度看非阻塞。 API仍然需要使用阻塞(在工作线程中)或异步I / O来实际完成操作。否则,套接字将需要一个自旋锁,并产生CPU浸泡。
您需要查看实现的其余部分,以了解如何完成此映射。