HttpConnector请求处理分工如下:
1、ServerSocket等待接受Http请求连接;
2、请求到达,从HttpProcessor处理池获取处理对象;
3、委托给HttpProcessor具体处理请求;
4、当前HttpConnector继续等得下一个Http请求;
具体HttpConnector和HttpProcessor如何实现异步工作机制?
HttpConnector和HttpProcessor两者都实现Runnable接口,并且两者本身运行在自身线程中。
这里我们称HttpConnector实例中run方法所在线程为连接器线程;而HttpProcessor实例中run方法所在线程为处理器线程。
首先看下HttpConnector对应连接器线程的run方法,主要工作:
1、阻塞等待Http请求;
2、为每个请求分配一个HttpProcessor对象;
3、调用HttpProcessor的process()方法处理;
public void run() {
// 循环,直到shutdown
while (!stopped) {
// 监听socket
Socket socket = serverSocket.accept();
// 为socket分配处理器
HttpProcessor processor = createProcessor();
// 如果当前没有空闲处理器
if(processor == null) {
// 忽略请求,不做处理
}
// 执行处理
processor.assign(socket);
}
}HttpConnector中run方法所在连接器线程进入HttpProcessor对象的assign()方法,如下:
synchronized void assign(Socket socket) {
// 等待前一个socket被Processor获取,Processor获取后会调用totify唤醒当前线程,
// 然后当前线程把socket赋给Processor全局socket
while (available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// 当前最新socket赋值给全局变量,并唤醒processor等待线程(等待socket)
this.socket = socket;
available = true;
// 唤醒处理器线程
notifyAll();
}此处变量available表示当前HttpProcessor对象中是否存在一个新的Socket套接字连接(也即是否有新的请求),初始available为false,表示初始没有socket连接。
assign程序流分两种情况:
1、当前available=false(表示当前HttpProcessor对象中不存在新的Socket可以获取),无需等待,直接将当前HttpConnector传递过来的最新socket传给HttpProcessor,
同时设置available=true(表示当前HttpProcessor对象中存在新的Socket需要处理),唤醒处理器线程(之前处理器线程阻塞等待新的Socket到达);
2、当前available=true(表示当前HttpProcessor对象中存在未处理的新Socket),则wait方法会阻塞,直到HttpProcessor处理器线程获取前一个新的Socket,并通知我唤 醒,之后再进行第一步处理。
不管是情况1还是情况2,HttpConnector实例对应的连接器线程进去assign方法后,阻塞等待,之后负责把socket传给HttpProcessor,之后则直接返回,也就是并没有等待请求处理完毕再返回,HttpProcessor对应的处理器线程继续处理请求,而HttpConnector对应的连接器线程则继续等待下一个Http请求,此时便是异步实现的方式。
接下来看下HttpProcessor对应处理器线程的run方法,主要工作:、
1、await()会阻塞等待,直到HttpConnector对应连接器线程将新的socket传给HttpProcessor全局变量,并唤醒当前处理器线程;
2、获取新的socket之后,调用process()进行实际请求处理;
3、处理完毕后将当前自身处理器线程放入空闲队列中;
public void run() {
while (!stopped) {
// 阻塞等待,直到下一个新的socket被赋值给全局变量
Socket socket = await();
if (socket == null)
continue;
// Process the request from this socket
try {
process(socket);
} catch (Throwable t) {
log("process.invoke", t);
}
// 放入空闲处理器池中
connector.recycle(this);
}
}看下await()方法,await()方法主要阻塞等待,直到HttpConnector对应线程将新的socket传给HttpProcessor全局变量,并唤醒通知我新的Socket已经到达。
此时await()将全局新的socket获取过来,并标志available为false,表示新的socket已经获取,没有新的socket了,notifalAll()告知HttpConnector又可以传新的socket进来。
private synchronized Socket await() {
// 等待被唤醒,唤醒者为connector线程
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}
Socket socket = this.socket;
available = false;
// 通知已经获取最新socket,下一个socket可以赋值进来
notifyAll();
return (socket);
}虽然assign()方法和await()方法都属于HttpProcessor实例的方法,但是两者被不同线程所调用执行,assign()由HttpConnector中run方法所在线程调用,而await()由HttpProcessor中run方法所在线程调用。两者通过共享变量available实现协同工作,并通过全局socket变量来进行数据传输工作。
两者线程的程序流如下:
本文详细介绍了Tomcat中HttpConnector和HttpProcessor如何实现异步工作机制。HttpConnector等待请求,分配HttpProcessor处理,然后继续等待下一个请求;HttpProcessor获取Socket后进行请求处理,完成后返回空闲队列,实现线程间的协同处理,达到异步效果。
785

被折叠的 条评论
为什么被折叠?



