当前位置: 首页 > news >正文

Servlet生命周期和线程安全

在这里插入图片描述

✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:JAVA开发者成长之路
✨特色专栏:国学周更-心性养成之路
🥭本文内容:Servlet生命周期和线程安全
更多内容点击👇
      Servlet转发与重定向

本文目录

  • 一、Servlet生命周期
    • 1、生命周期四个阶段
      • 1.1、实例化
      • 1.2、初始化
      • 1.3、服务
      • 1.4、销毁
      • 1.5、Servlet执行流程
  • 二、Servlet特性
    • 1、线程安全问题
    • 2、如何保证线程安全

在这里插入图片描述

一、Servlet生命周期

1、生命周期四个阶段

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 初始化后调用 init () 方法。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 销毁前调用 destroy() 方法。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

现在让我们详细讨论生命周期的方法。

1.1、实例化

  当用户第一次访问Servlet时,由容器调用Servlet的构造器创建具体的Servlet对象。也可以在容器启动之后立刻创建实例。使用如下代码可以设置Servlet是否在服务器启动时就创建。

实例化只执行一次。

    public LifeServlet() {
        System.out.println("1、完成实例化");
    }

1.2、初始化

  在初始化阶段,init()方法会被调用。在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。

  Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

  当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

init()方法只被执行一次

    public void init() throws ServletException {
        super.init();
        System.out.println("2、完成初始化");
    }

1.3、服务

  当客户端有一个请求时,容器就会将请求ServletRequest与响应ServletResponse对象转给Servlet,以参数的形式传给service方法。

  每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

service()方法会执行多次

public void service(ServletRequest request, 
                    ServletResponse response) 
      throws ServletException, IOException{
}

  doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征。

doGet() 方法

  GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

public void doGet(HttpServletRequest request,
                  HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

doPost() 方法

  POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

public void doPost(HttpServletRequest request,
                   HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

1.4、销毁

  当Servlet容器停止或者重新启动都会引起销毁Servlet对象并调用destroy方法

  destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

  在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。

destroy()方法执行一次

    public void destroy() {
        super.destroy();
        System.out.println("4、销毁了");
    }

1.5、Servlet执行流程

在这里插入图片描述

  1. 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
  2. Servlet 容器在调用 service() 方法之前加载 Servlet。
  3. 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

/**
 * 演示Servlet的生命周期
 * 1、实例化
 * 2、init:初始化
 * 3、service:服务
 * 4、destory:销毁
 */

@WebServlet("/LifeServlet")
public class LifeServlet extends HttpServlet {

    public LifeServlet() {
        System.out.println("1、完成实例化");
    }

    @Override
    public void init() throws ServletException {
        super.init();
        System.out.println("2、完成初始化");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("3、就绪中");
        response.getWriter().append("Served at:").append(request.getContextPath());
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    public void destroy() {
        super.destroy();
        System.out.println("4、销毁了");
    }
}

二、Servlet特性

1、线程安全问题

  Servlet在访问之后,会执行实例化操作,创建一个Servlet对象。而我们Tomcat容器可以同时多个线程并发访问同一个Servlet,如果在方法中对成员变量做修改操作,就会有线程安全问题。

2、如何保证线程安全

  1. synchronize

    • 将存在线程安全问题的代码放到同步代码块中
  2. 实现SingleThreadModel接口

    • servlet实现SingleThreadMode接口后。每个线程都会创建servlet实例,这样每个客户端请求就不存在共享资源的问题,但是servlet响应客户端的效率太低,所以已经淘汰。
  3. 尽可能使用局部变量

    将全局变量public boolean status;改为局部变量boolean status = true;

public class TestServlet extends HttpServlet{
 
//    public  boolean status;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        boolean status = true;
        String cmd = req.getParameter("cmd");
        if (cmd.contains("Calculator")) {
            status = false;
            try {
                Thread.sleep(1000);
            }catch (Exception e){
 
            }
        }
 
        if (!status) {
            return;
        }
        if (cmd.contains("Calculator")){
            resp.getWriter().write(cmd);
        }
    }
}

  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

相关文章:

  • 【C++进阶】C++11新特性下篇(万字详解)
  • 一文读懂于Zebec生态中的潜在收益方式
  • 蓝桥杯有必要参赛吗?
  • 移植MQTT-C库(附源码)
  • 创建Series()对象--pandas
  • 【Linux】软件包管理器yum
  • 算法刷题打卡第49天:排序数组---计数排序
  • 【Linux】低级IO
  • 【Linux】shell命令以及运行原理
  • 【解决】Unity Player Log 自生成造成磁盘满占用率问题
  • 犀牛插件开发-基础核心-技术概览-总体架构-教程
  • 看2022年卡塔尔世界杯有感
  • 小黑被劝退了,生活学习依然继续的leetcode之旅:572. 另一棵树的子树
  • 数据库原理及MySQL应用 | 日志管理
  • web前端经典react面试题
  • 自己简单写的 事件订阅机制
  • [Vue CLI 3] 配置解析之 css.extract
  • 2017-08-04 前端日报
  • Create React App 使用
  • DOM的那些事
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Node + FFmpeg 实现Canvas动画导出视频
  • Python实现BT种子转化为磁力链接【实战】
  • Sass Day-01
  • Vim Clutch | 面向脚踏板编程……
  • XML已死 ?
  • 从输入URL到页面加载发生了什么
  • 从伪并行的 Python 多线程说起
  • 十年未变!安全,谁之责?(下)
  • 使用Gradle第一次构建Java程序
  • 我有几个粽子,和一个故事
  • 容器镜像
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​io --- 处理流的核心工具​
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • # 安徽锐锋科技IDMS系统简介
  • #FPGA(基础知识)
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #单片机(TB6600驱动42步进电机)
  • $.ajax,axios,fetch三种ajax请求的区别
  • (1)Android开发优化---------UI优化
  • (floyd+补集) poj 3275
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)视频码率,帧率和分辨率的联系与区别
  • .bat批处理出现中文乱码的情况
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .Net FrameWork总结
  • .NET 中 GetProcess 相关方法的性能
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装