目录
一、Servlet生命周期
1、生命周期的四个阶段
1.1 实例化
1.2 初始化
1.3 服务
1.4 销毁
2、Servlet执行流程
3、代码演示
二、 Servlet特性
1、线程安全问题
2、如何保证线程安全
一、Servlet生命周期
1、生命周期的四个阶段
1.1 实例化
当用户第一次访问Servlet时,由容器调用Servlet的构造器创建具体的Servlet对象。也可以在容器启动之后立刻创建实例。使用如下代码可以设置Servlet是否在服务器启动时就创建。
实例化只执行一次。
1.2 初始化
在初始化阶段,init()方法会被调用。这个方法在javax.servlet.Servlet接口中定义,init()方法以一个ServletConfig类型的对象作为参数。
init()方法只被执行一次
1.3 服务
当客户端有一个请求时,容器就会将请求ServletRequest与响应ServletResponse对象转给Servlet,以参数的形式传给service()方法。
service()方法会被执行多次
1.4 销毁
当Servlet容器停止或者重新启动都会引起销毁Servlet对象并调用destroy()方法。
destroy()方法只执行一次
2、Servlet执行流程
3、代码演示
package com.java.servlet;
import javax.servlet.*;
import java.io.IOException;
public class LifeServlet implements Servlet {
public LifeServlet() {
System.out.println("1:完成实例化");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2:完成初始化");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig()");
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3:就绪中");
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo()");
return null;
}
@Override
public void destroy() {
System.out.println("4:销毁了");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>life</servlet-name>
<servlet-class>com.java.servlet.LifeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>life</servlet-name>
<url-pattern>/LifeServlet</url-pattern>
</servlet-mapping>
</web-app>
二、 Servlet特性
1、线程安全问题
Servlet在访问之后,会执行实例化操作,创建一个Servlet对象。而我们Tomcat容器可以同时多个线程并发访问同一个Servlet,如果在方法中对成员变量做修改操作,就会有线程安全问题。
2、如何保证线程安全
(1)synchronize
将存在线程安全问题的代码放到同步代码块中;
(2)实现SingleThreadModel接口
servlet实现SingleThreadMode接口后。每个线程都会创建servlet实例,这样每个客户端请求就不存在共享资源的问题,但是servlet响应客户端的效率太低,所以已经淘汰。
(3)尽可能使用局部变量