Java web 实际上是用线程池处理请求的。下面介绍什么叫做线程池,以及如何正确的配置线程池。
单线程模型
web服务器的最底层实际上是一个socket,这个socket监听并接收达到的tcp连接,这个连接被建立时就可以通过解析、读取文件,然后将这个信息封装成一个http请求,这个请求被移交至web应用程序。
ServerSocket listener = new ServerSocket(8080);
try {
while (true) {
Socket socket = listener.accept();
try {
handleRequest(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
listener.close();
}
单线程模型,只有一个线程处理所有的socket,只有在处理完一个请求后才能处理另一个请求,在实际应用中handleRequest方法可能需要经过100毫秒才能返回这样服务器在处理请求时需要的时间比较久。
多线程模型
尽管handleRequest可能会被IO操作阻塞,CPU却可能是空闲的,它可以处理其它更多请求,但这对单线程模型来说是不能实现的。因此,通过创建多个线程,可以使服务器程序实现并发操作:
public static class HandleRequestRunnable implements Runnable {
final Socket socket;
public HandleRequestRunnable(Socket socket) {
this.socket = socket;
}
public void run() {
try {
handleRequest(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Main loop here
ServerSocket listener = new ServerSocket(8080);
try {
while (true) {
Socket socket = listener.accept();
new Thread( new HandleRequestRunnable(socket) ).start();
}
} finally {
listener.close();
}
accept()方法仍然是在一个单线程循环中被调用。但是当TCP连接建立,socket创建时,服务器就创建一个新的线程。这个新生的线程将执行和单线程模型中一样的handleRequest方法。