看这篇文章之前,请先阅读:
how tomcat works 读书笔记 十一 StandWrapper 上 地址如下:
http://blog.csdn.net/dlf123321/article/details/41247693
在tomcat中,用户的一个请求会被一个servlet来处理。
那么当第一个人请求servletA时,它会在tomcat内部的类加载器中加载,得到一个servletA类的实例。
那个第二个人请求servletA时,又怎么办呢?是再得到一个新的实例还是怎么着?
话不多说看代码
public Servlet allocate() throws ServletException { // If not SingleThreadedModel, return the same instance every time if (!singleThreadModel) { // Load and initialize our instance if necessary if (instance == null) { // 如果instance为null 就调用loadServlet synchronized (this) { // 返回一个新的 if (instance == null) instance = loadServlet(); } } if (!singleThreadModel) { //如果已经有instance了 直接返回就ok countAllocated++; return (instance); } } synchronized (instancePool) { //能运行到这里,说明一定是实现了singleThreadModel while (countAllocated >= nInstances) { //会给池中不断地放置servlet if (nInstances < maxInstances) { instancePool.push(loadServlet()); nInstances++; } else { instancePool.wait(); } } countAllocated++; return (Servlet) instancePool.pop(); //最后返回顶上的一个 }
所以我们能得出一个结论,如果servlet没有实现singleThreadModel,那么第一次请求它时,返回一个新的,第二次就还是它本身了。如果实现了singleThreadModel,tomcat会维持一个servlet池,每次请求,都给你一个池里的对象。
如果你看完了我文章开头推荐的博客,应该就明白了为什么SingleThreadModel会被废弃了。
那么说到底,如果没有SingelThreadModel,多线程的问题怎么办?
既然问的了这里,那我就得先问一个问题了:如果是多线程,能有什么问题?
请参考http://www.cnblogs.com/gw811/archive/2012/09/07/2674859.html
另外在上面的文章中,如果我们只使用局部变量而不用实例变量,就可以不用synchronized(this){} 这个保护。
通过上面的阅读我们知道
解决线程问题的最好方法就是避免使用servlet类的内部变量。但这是一种非语法级的保护措施,程序员还是可能会犯这个错误的。
因此最好的方法就是引入ThreadLocal模式。这个模式,我们在后面会再讲。
参考资料
http://blog.csdn.net/dlf123321/article/details/41247693
http://www.cnblogs.com/gw811/archive/2012/09/07/2674859.html