servlet cig比较,生命周期,init service destory

1 Servlet 与 CGI 的比较

和CGI程序一样,Servlet可以响应用户的指令(提交一个FORM等等),也可以象CGI程序一样,收集用户表单的信息并给予动态反馈(简单的注册信息录入和检查错误)。
然而,Servlet的机制并不仅仅是这样简单的与用户表单进行交互。传统技术中,动态的网页建立和显示都是通过CGI来实现的,但是,有了Servlet,您可以大胆的放弃所有CGI(perl?php?甚至asp!),利用Servlet代替CGI,进行程序编写。
    对比一:当用户浏览器发出一个Http/CGI的请求,或者说 调用一个CGI程序的时候,服务器端就要新启用一个进程 (而且是每次都要调用),调用CGI程序越多(特别是访问量高的时候),就要消耗系统越多的处理时间,只剩下越来越少的系统资源,对于用户来说,只能是漫长的等待服务器端的返回页面了,这对于电子商务激烈发展的今天来说,不能不说是一种技术上的遗憾。
而Servlet充分发挥了服务器端的资源并高效的利用。每次调用Servlet时并不是新启用一个进程 ,而是在一个Web服务器的进程敏感词享和分离线程,而线程最大的好处在于可以共享一个数据源,使系统资源被有效利用。
    对比二:传统的CGI程序,不具备平台无关性特征,系统环境发生变化,CGI程序就要瘫痪,而Servlet具备Java的平台无关性,在系统开发过程中保持了系统的可扩展性、高效性。
    对比三:传统技术中,一般大都为二层的系统架构,即Web服务器+数据库服务器,导致网站访问量大的时候,无法克服CGI程序与数据库建立连接时速度慢的瓶颈,从而死机、数据库死锁现象频繁发生。而我们的Servlet有连接池的概念,它可以利用多线程的优点,在系统缓存中事先建立好若干与数据库的连接,到时候若想和数据库打交道可以随时跟系统"要"一个连接即可,反应速度可想而知。

servlet 声明周期:1初始化 调用init()方法  ;2响应客户请求阶段 调用service()方法; 3终止阶段 调用destory()方法
请求过来 由 service 方法处理, 再选择调用doGet或doPost方法

service()是在javax.servlet.Servlet接口中定义的, 在 javax.servlet.GenericServlet 中实现了这个接口。GenericServlet定义了 servlet 生命周期,
doGet/doPost 则是在 javax.servlet.http.HttpServlet 中实现的
javax.servlet.http.HttpServlet是javax.servlet.GenericServlet 的子类

链接:https://www.nowcoder.com/questionTerminal/3f368578e43d48b1968d79b935d00972
来源:牛客网

1.service方法是在servlet生命周期中的服务期,默认在HttpServlet类中实现,根据HTTP请求方法(GET、POST等),将请求分发到doGet、doPost等方法实现。
2.GenericServlet 抽象类给出了设计servlet的一些骨架,定义了servlet生命周期还有一些得到名字、配置、初始化参数的方法,其设计的是和应用层协议无关的。doget/dopost与Http协议有关,是在 javax.servlet.http.HttpServlet 中实现的。
3.doGet和doPost方法在HttpServlet类中实现,GenericServlet中实现了service()
4.常说所有的请求都先由service方法处理,而javax.servlet.GenericServlet接口实现了javax.servlet.Servle接口,且javax.servlet.http.HttpServlet 是 javax.servlet.GenericServlet 的子类。只有最先定义好了的service方法才可以处理所有的请求。

servlet中init,service,destroy方法描述:
init方法: 是在servlet实例创建时调用的方法,用于创建或打开任何与servlet相的资源和初始 化servlet的状态,Servlet规范保证调用init方法前不会处理任何请求 
 service方法:是servlet真正处理客户端传过来的请求的方法,由web容器调用, 根据HTTP请求方法(GET、POST等),将请求分发到doGet、doPost等方法 
destory方法:是在servlet实例被销毁时由web容器调用。Servlet规范确保在destroy方法调用之 前所有请求的处理均完成,需要覆盖destroy方法的情况:释放任何在init方法中 打开的与servlet相关的资源存储servlet的状态
 
init():在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。 service():它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。 destroy(): 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。
 
Servlet的生命周期分为5个阶段:加载、创建、初始化、处理客户请求、卸载。

(1)加载:容器通过类加载器使用servlet类对应的文件加载servlet

(2)创建:通过调用servlet构造函数创建一个servlet对象

(3)初始化:调用init方法初始化

(4)处理客户请求:每当有一个客户请求,容器会创建一个线程来处理客户请求

(5)卸载:调用destroy方法让servlet自己释放其占用的资源

 

Servlet是线程不安全的,在Servlet类中可能会定义共享的类变量,这样在并发的多线程访问的情况下,不同的线程对成员变量的修改会引发错误。

servlet 对象在 tomcat 服务器是单实例多线程的。 因为 servlet 是多线程的,所以当多个 servlet 的线程同时访问了 servlet 的共享数据,如成员变量,可能会引发线程安全问题。
   解决办法:

                                     1 )把使用到共享数据的代码块进行同步(使用 synchronized 关键字进行同步)

                                     2 )建议在 servlet 类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

原文地址:https://www.cnblogs.com/wsnan/p/12292120.html