servlet线程模型

讲servlet之前要先讲一下servlet容器,
Servlet容器是web server或application server的一部分,供基于请求/响应发送模型的网络服务,解码基
于 MIME 的请求,并且格式化基于 MIME 的响应。Servlet 容器也包含并管理 Servlet 生命周期。
所以对于servlet的线程模型和它所依赖的容器有关系。
tomcat是最常用的servlet容器。

Tomcat介绍

Tomcat是Apache基金会下的一个开源项目。。。。。。。。。。

实现了对Servlet和JSP的支持,并提供了作为Web服务器的一些特有功能

Tomcat提供了一个Jasper编译器用以将JSP编译成对应的Servlet。

(上面都是废话)

Tomcat的处理过程

Tomcat对servlet的处理的过程是:

  1. 客户端第一次请求Servlet的时候,tomcat会根据web.xml配置文件实例化servlet
  2. 当又有一个客户端访问该servlet的时候,不会再实例化该servlet

tomcat自己维护了一个线程池,在收到请求时,会到池子里找可用的线程。如果找不到可用的线程,并且线程池已经到了最大线程数,那么请求就会放到一个队列中等待获取可用的线程。

举个栗子:
创建一个Servlet,每次去请求都打印出来自己的hashcode

public class MyServlet extends HttpServlet{
    private Logger logger = Logger.getLogger(this.getClass());
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        logger.debug(this.hashCode());
    }
}

结果是这样的:

会发现每次请求的servlet都是同一个,也就是每个servlet只有一个实例。

所以servlet是线程不安全的,如果使用静态或者实例变量中存储请求和响应对象,那么在多线程去情况下一定会出现问题。

设计线程安全的Servlet

实现SingleThreadModel接口

SingleThreadModel接口是一个标识接口,如果实现了这个接口,那么Tomcat就会保证一个时刻只有一个线程对这个servlet进行操作,其他的线程排着队慢慢来。

这种方式虽然安全,但是太低效了。
因此Servlet的规范中已经被废弃了。

使用同步的类

对集合进行操作的时候,选则同步的集合就不会有线程不安全的问题了

Synchronized关键字

多个servlet对外部对象进行操作,一定要上锁,这种锁机制效率也很慢。

使用局部变量

变量都是局部变量,用完就回收了,再用再创建。

属性的线程安全

ServletContext是线程不安全的,多线程下可以同时进行读写,因此我们要对其读写操作进行同步或者深度的clone。

HttpSession是线程不安全的,和ServletContext的操作一样。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容