Servlet体系结构、生命周期、多线程并发问题。
一、Servlet是什么?
Servlet是基于Java语言的Web服务器端编程技术,按照Java EE规范定义,Servlet是运行在Servlet容器中的Java类,它能处理Web客户的HTTP请求,并产生HTTP响应。
Servlet对请求的处理和响应过程分为如下几个步骤:
1.接收HTTP请求;
2.取得请求信息,包括请求头和请求参数数据;
3.调用其他Java类方法,完成具体的业务功能;
4.实现到其他Web组件的跳转(包括重定向或请求转发);
5.生成HTTP响应(包括HTML或非HTML响应)。
1.Servlet体系结构
- Servlet是使用Servlet API(应用程序设计接口)及相关类和方法的Java程序。
- Servlet API包含两个软件包:
- javax.servlet包
- 定义了所有Servlet类都必须实现或继承的通用接口和类
- javax.servlet.http包
- 定义了采用HTTP协议通信的HttpServlet类。
- javax.servlet包
3.Servlet API的主要接口和类之间的关系
2.Servlet生命周期
1.Servlet生命周期是指Servlet实例从创建到响应客户请求,直至销毁的过程。Servlet程序本身不直接在Java虚拟机上运行,由Servlet容器负责管理其整个生命周期。
2. Servlet生命周期可分为四个阶段:实例化、初始化、处理请求、销毁。
Servlet容器在如下时刻加载和实例化一个Servlet:
Servlet容器启动后,客户首次向Servlet发出请求,Servlet容器会判断内存中是否存在指定的Servlet对象,如果没有则创建它,然后根据客户的请求创建HttpRequest、HttpResponse对象,从而调用Servlet 对象的service方法。
在为Servlet配置了自动装入选项(load-on-startup)时,服务器在启动时会自动装入此Servlet。
Servlet 初始化:
实例化后,Servlet容器将调用Servlet的init方法来对Servlet实例进行初始化,初始化成功,Servlet在Web容器中会处于服务可用状态;如果初始化失败,Servlet容器会销毁该实例;
当Servlet运行出现异常时,Servlet容器会使该实例变为服务不可用状态。
请求处理:
服务器接收到客户端请求,会为该请求创建“请求”对象和“响应”对象,并调用service()方法,service()方法再调用其他方法来处理请求。
在Servlet生命周期中,service()方法可能被多次调用。当多个客户端同时访问某个Servlet的service()方法时,服务器会为每个请求创建一个线程,这样可以并行处理多个请求,减少请求处理的等待时间,提高服务器的响应速度。但同时也要注意对同一对象的并发访问问题。
服务终止:
当Servlet容器需要终止Servlet(如Web服务器被关闭或需要出让资源),它会先调用Servlet的destroy()方法使其释放正在使用的资源。
在调用destroy()方法之前,必须让当前正在执行service()方法的任何线程完成执行,或者超过了服务器定义的时间限制。
在destroy()方法完成后,Servlet容器必须释放Servlet实例以便被垃圾回收。
3.Servlet的多线程并发问题
由于servlet在Tomcat中是以单例模式存在的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。多线程下每个线程对局部变量都会有自己的一份copy,这样对局部变量的修改只会影响到自己的copy而不会对别的线程产生影响,线程安全的。
解决办法:建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。