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都是同一个变量,那么线程安全性就很难保证。所以建议第一种方法。
最后请求结束,放回线程池,等到被调用;