Servlet的继承树,生命周期和线程不安全

1、Servlet 继承树

java 复制代码
3)Servlet的继承树
- Servlet接口
   public interface Servlet{
       public void init(config);
       public void service(request,response);
       public void destroy();
   }
- GenericServlet抽象类
   public abstract class GenericServlet implements Servlet{
       实现了init方法和destroy方法。service方法仍然保持抽象
   }
- HttpServlet抽象类 - 最初设计时,基于http协议,因此产生了HttpServlet,将来可能会基于其他协议出现其他协议下的Servlet
   public abstract class HttpServlet extends GenericServlet{
        实现了service方法。然后重载了service方法
        protected void service(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{
            String method=request.getMethod();
            if("POST".equals(method)){
                doPost(request,response);
            }else if("PUT".equals(method)){
                doPut(...)
            }else{...
            }
        }
        细化了服务方法:
        public void doPost(){}
        public void doGet(){}
        public void doDelete(){}
        public void doPut(){}
   }

2、Servlet 生命周期

XML 复制代码
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.csdn</groupId>
            <artifactId>pro03-fruit-optimize</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
java 复制代码
package com.csdn.servlet;
import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebServlet;
import java.io.IOException;
//4、演示Servlet生命周期
@WebServlet("/h04")
public class ServletLifecycle extends GenericServlet {
    // tomcat被执行的时候,他是不会被实例化的,这样是比较合理的
    // 因为假设项目里面有一万个Servlet,tomcat在启动的时候,
    // 就要实例化一万个实例对象,但是一万个也不知道用户什么时候来访问,
    // 放在tomcat里面,就会使tomcat启动的时间拉长,延迟实例化,只执行一次
    public ServletLifecycle() {
        System.out.println("ServletLifecycle正在实例化....");
    }
    //当有请求到来时,会被执行,多次请求可以执行多次
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("ServletLifecycle正在服务....");
    }
    //请求到来时,先实例化,然后执行init方法,只执行一次,然后执行service方法
    @Override
    public void init() throws ServletException {
        System.out.println("ServletLifecycle正在初始化....");

    }
    //tomcat停止时,执行destroy方法
    @Override
    public void destroy() {
        System.out.println("ServletLifecycle正在销毁....");
    }
}
java 复制代码
4)Servlet的生命周期
- Servlet是tomcat去实例化的,不是程序员new的
- Servlet中的服务方法也不是程序员主动调用的,也是由tomcat去调用的。当有请求到来时,tomcat通过反射执行service方法
- Servlet的生命周期分为四个阶段:实例化、初始化、服务、销毁
- 默认情况下,Servlet不会随着容器的启动而被实例化,而是当第一次有人请求我的时候,我才会被实例化
  当容器停止时,容器中的Servlet实例会被销毁,destroy方法被调用

3、Servlet 线程不安全问题

java 复制代码
package com.csdn.servlet;
import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebServlet;
import java.io.IOException;
//5、演示线程不安全的问题
@WebServlet("/h05")
public class ThreadUnsafeServlet extends GenericServlet {
    public Integer i = 1;
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        if (i % 2 == 0) {
            System.out.print("A");
        } else {
            System.out.print("B");
        }
        i++;
    }
}
java 复制代码
- Servlet在tomcat容器中是单实例的是线程不安全的
        ① 单实例的意思是:所有客户端发过来的请求都是同一个ServletLifecycle实例来处理
            第一个用户发请求过来时,容器会去实例化servlet,然后进入服务阶段,从此之后,所有的请求到来时,直接执行服务方法
        ② 线程不安全的意思时:既然所有的请求到来时是同一个servlet实例去处理的,那么这些请求之间不能共用数据(共用变量)
            什么情况下共用变量?servlet中有成员变量,而服务方法中需要根据成员变量的值决定程序流程
            如果第一个请求到来时,执行服务方法,然后在服务方法中更改成员的值,从而就会导致其他的请求到来时流程发生变化
            小结:线程不安全的本质是:Servlet由成员变量;成员变量的值可能发生变化;业务逻辑依赖于这个变量
        ③ 如何解决线程不安全的问题:尽量避免使用成员变量;如果非要使用成员变量,那么要注意业务逻辑不要受成员变量值影响
相关推荐
冰淇淋烤布蕾10 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺16 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
Jakarta EE33 分钟前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)41 分钟前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
java—大象1 小时前
基于java+springboot+layui的流浪动物交流信息平台设计实现
java·开发语言·spring boot·layui·课程设计
杨哥带你写代码2 小时前
网上商城系统:Spring Boot框架的实现
java·spring boot·后端
camellias_2 小时前
SpringBoot(二十一)SpringBoot自定义CURL请求类
java·spring boot·后端
布川ku子2 小时前
[2024最新] java八股文实用版(附带原理)---Mysql篇
java·mysql·面试
憶巷2 小时前
Servlet的生命周期
servlet
向阳12182 小时前
JVM 进阶:深入理解与高级调优
java·jvm