1.Servlet是如何处理多个请求同时访问呢?
回答:servlet是默认采用单实例,多线程的方式进行。只要webapp被发布到web容器中的时候,servlet只会在发布的时候实例化一次,servlet在其生命周期中只有在将项目给移除或服务器stop的时候才会销毁,那么一个web项目从发布到运行只存在一个servlet的实例。
servlet等一些web容器中有线程池ThreadPool。此处先贴出tomcat7.0.3中的server.xml里面的代码:
1
2
3
4
5
|
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
|
1
2
3
4
5
6
|
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
|
从这两处可以看到通过配置web容器可以在线程池里面设置线程的数量。
当请求到达时,Servlet容器通过调度线程(Dispatchaer Thread)调度它管理下的线程池中等待执行的线程(Worker Thread)给请求者;
出现不同的线程同一时间访问同一个servlet的时候,其实servlet的对象只有一个,但是由于是tomcat支持多线程的原因,每个客户端请求执行的servlet中的函数都是在自己所支配的那一小段线程里面执行了,也就是说两个用户都登陆,都访问login方法,但是这是有用的是一个servlet但是局部的方法是放在不同的线程里面的。
比较一下两种方法:
1
2
3
4
5
6
7
|
public
class
Test1{
...
public
void
fun1(){
String s =
""
;
System.out.print(s);
}
}
|
1
2
3
4
5
6
7
|
public
class
Test2{
...
String s ;
public
void
fun1(){
System.out.print(s);
}
}
|
第一种Test1 如果Test1只有一个实例化对象,那么不同的用户访问他的话,每一个用户执行的fun1方法都是由自身的线程单独开辟的空间的。
第二种Test2 如果Test2只有一个实例化对象,那么不同的用户访问他的话,那每一个用户访问的s都是同一个变量,那么线程安全性就很难保证。所以建议第一种方法。
最后请求结束,放回线程池,等到被调用;