一个简单的异步Http连接器

本文通过实现一个简单的HttpConnector和HttpProcessor,深入探讨Tomcat连接器的工作原理。利用多线程机制处理HTTP请求,展示了如何接收并分配任务到各个处理器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=medium]
前两天看了Tomcat连接器部分的源码,Tomcat 4默认的连接器随意已经过时了,但是是一个很好的学习工具。它里面用了多线程的机制使得HttpProcesor异步处理。我但是也是看了很长时间,最后大部分看懂了,但是还有很多没有看懂。我自己写了一个很简单的一个连接器HttpConnector,一个HttpProcessor,帮助大家理解它,先看看程序吧。
[/size]
[size=medium]
BootStrap类很简单,就是使得HttpConnector监听socket请求,这个很好理解。
[/size]

public class BootStrap {
public static void main(String[] args){
HttpConnector connector = new HttpConnector();
connector.start();
System.out.println("Server is started, listened in 9999!");
}
}

[size=medium]
下面是一个比较复杂的HttpConnector类,它首先会创建ServerSocket,然后启动线程,创建minProcessors个HttpProcesor,并使它们都启动起来。
[/size]

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Stack;


public class HttpConnector implements Runnable{
private ServerSocket serverSocket;

private int minProcessors = 1;

private int maxProcessors = 5;

private int curProcessors = 0;

private Stack<HttpProcessor> processors = new Stack<HttpProcessor>();

private boolean stopped = false;

public void run() {
try {
while(!stopped){
Socket socket = serverSocket.accept();

HttpProcessor processor = createProcessor();

if(processor != null) {
processor.assign(socket);
} else {
System.out.println("Socket is no resource to be handled!");
}

socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void recycle(HttpProcessor processor){
processors.push(processor);
}

public void start(){
try {
serverSocket = new ServerSocket(9999);
} catch (IOException e) {
e.printStackTrace();
}

Thread thread = new Thread(this);
thread.start();

while(curProcessors < minProcessors){
if(maxProcessors > 0 && curProcessors >= maxProcessors){
break;
}
HttpProcessor processor = newProcessor();
processors.push(processor);
}
}

private HttpProcessor newProcessor() {
HttpProcessor processor = new HttpProcessor(this,curProcessors++);
processor.start();
return processor;
}

private HttpProcessor createProcessor(){
synchronized(processors){
if(processors.size() > 0){
return processors.pop();
} else {
if(maxProcessors > 0 && curProcessors < maxProcessors){
return newProcessor();
} else {
if(maxProcessors < 0){
return newProcessor();
} else {
return null;
}
}
}
}
}

}

[size=medium]
下来一个是HttpProcessor,在线程启动后,会调用await方法,使得当前线程等待,有个Socket请求来临之后,调用assign方法,使得当前线程继续运行,但是assign方法会返回,HttpConnector就可以继续相应请求了。在HttpProcessor处理完了之后,HttpPrcoessor会重新放到栈中,就可以进行复用了。这个来的线程同步感觉看了很久还是明白了,但是我估计
现在还写不出来。
[/size]

import java.net.Socket;


public class HttpProcessor implements Runnable{
private HttpConnector connector;

private int processorId;

private Socket socket;

private boolean avaliable = false;

private boolean stopped = false;

public HttpProcessor(HttpConnector connector, int processorId){
this.connector = connector;
this.processorId = processorId;
}

public void run(){
while(!stopped){
Socket socket = await();

process(socket);

connector.recycle(this);
}
}

public void process(Socket socket){
System.out.println("Processor " + processorId + " Process socket :" + socket.getPort());
}

public void start(){
Thread thread = new Thread(this);
thread.start();
}

public synchronized Socket await(){
while(!avaliable){
try {
System.out.println("Process " + processorId + " is ready!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

avaliable = false;
Socket socket = this.socket;
notifyAll();
return socket;
}

public synchronized void assign(Socket socket){
while(avaliable){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
avaliable = true;
this.socket = socket;
notifyAll();
}
}

[size=medium]
最后贴上客户端程序,这个我们是来测试服务器端运行的,也很好理解。
[/size]

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;


public class Client {
public static void main(String[] args){
for(int i = 0; i < 100; i++){
Socket socket = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"),9999);
System.out.println("Socket is started, socket id is:" + socket.getPort());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值