今天看到这篇博客,感觉还不错,拿来借鉴学习一下。

一、Servlet 是什么?

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:

  • 1、性能明显更好。
  • 2、Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
  • 3、Servlet 是独立于平台的,因为它们是用 Java 编写的。
  • 4、服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
  • 5、Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。

二、Servlet的生命周期

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

  • 1、Servlet 通过调用 init () 方法进行初始化。
  • 2、Servlet 调用 service() 方法来处理客户端的请求。
  • 3、Servlet 通过调用 destroy() 方法终止(结束)。
  • 4、最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

init() 方法

  init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。

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

service() 方法

  service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

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

destroy() 方法

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

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

三、怎样理解Servlet的单实例多线程?

不同的用户同时对同一个业务(如注册)发出请求,那这个时候容器里产生的有是几个servlet实例呢?

  答案是:只有一个servlet实例。一个servlet是在第一次被访问时加载到内存并实例化的。同样的业务请求共享一个servlet实例。不同的业务请求一般对应不同的servlet。

由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的安全性问题。

JSP的中存在的多线程问题: 
  当客户端第一次请求某一个JSP文件时,服务端把该JSP编译成一个CLASS文件,并创建一个该类的实例,然后创建一个线程处理CLIENT端的请求。如果有多个客户端同时请求该JSP文件,则服务端会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间。、

  对JSP中可能用的的变量说明如下: 
  实例变量: 实例变量是在堆中分配的,并被属于该实例的所有线程共享,所以不是线程安全的。 
  JSP系统提供的8个类变量 
  JSP中用到的OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT是线程安全的(因为每个线程对应的request,respone对象都是不一样的,不存在共享问题), APPLICATION在整个系统内被使用,所以不是线程安全的。

局部变量: 局部变量在堆栈中分配,因为每个线程都有它自己的堆栈空间,所以是线程安全的
静态类: 静态类不用被实例化,就可直接使用,也不是线程安全的.

外部资源: 在程序中可能会有多个线程或进程同时操作同一个资源(如:多个线程或进程同时对一个文件进行写操作).此时也要注意同步问题.

Servlet单实例多线程机制:

  Servlet采用多线程来处理多个请求同时访问。servlet依赖于一个线程池来服务请求。线程池实际上是一系列的工作者线程集合。Servlet使用一个调度线程来管理工作者线程。 
        当容器收到一个Servlet请求,调度线程从线程池中选出一个工作者线程,将请求传递给该工作者线程,然后由该线程来执行Servlet的service方法。当这个线程正在执行的时候,容器收到另外一个请求,调度线程同样从线程池中选出另一个工作者线程来服务新的请求,容器并不关心这个请求是否访问的是同一个Servlet.当容器同时收到对同一个Servlet的多个请求的时候,那么这个Servlet的service()方法将在多线程中并发执行。 
         Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间,对于Tomcat可以在server.xml中通过<Connector>元素设置线程池中线程的数目。

四、如何开发线程安全的Servlet

      1、实现 SingleThreadModel 接口 
  该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为:

Public class Concurrent Test extends HttpServlet implements SingleThreadModel { 
………… 
}  
  2、同步对共享数据的操作 

  使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段

       3、避免使用实例变量 

  本实例中的线程安全问题是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。 

五、servlet与jsp的区别

1. jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)

2. jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
3. Servlet中没有内置对象,内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到.Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。
 
4. 对于静态HTML标签,Servlet都必须使用页面输出流逐行输出

Javaweb基础--->Servlet(转载)的更多相关文章

  1. JavaWeb基础—Servlet

    一.Servlet是什么 是服务器上运行的Java小应用程序,并被称为JavaWeb三大组件之一 通常我们把实现了Servlet的类,称之为Servlet Servlet作用主要是 1.接收请求数据 ...

  2. JavaWeb基础-servlet

    Servlet简介 Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤: 1.编写一个Java类,实现s ...

  3. JavaWeb基础—Servlet重要对象

    一.ServletConfig对象 当servlet配置了初始化参数后(<init-param> <param-name> <param-value>),web容器 ...

  4. 关于java基础、多线程、JavaWeb基础、数据库、SSM、Springboot技术汇总

    作者 : Stanley 罗昊 本人自行总结,纯手打,有疑问请在评论区留言 [转载请注明出处和署名,谢谢!] 一.java基础 1.多态有哪些体现形式? 重写.重载 2. Overriding的是什么 ...

  5. JavaWeb基础: ServletContext

    基本概念 Web容器在启动时,会为每个Web应用程序都创建一个对应的ServletContext对象,它代表当前Web应用. ServletContext(javax.servlet.http.Ser ...

  6. JavaWeb基础: 学习大纲

    JavaWeb基础: Web应用和Web服务器 JavaWeb基础: Tomcat JavaWeb基础:HTTP协议和基于Restful的架构 JavaWeb基础: Web工程配置文件 JavaWeb ...

  7. JavaWeb基础知识总结

    JavaWeb基础知识总结.   1.web服务器与HTTP协议 Web服务器 l WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. l Internet上供 ...

  8. 超详细的Java面试题总结(四 )之JavaWeb基础知识总结

    系列文章请查看: 超详细的Java面试题总结(一)之Java基础知识篇 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java ...

  9. JavaWeb学习——Servlet相关的接口和类

    JavaWeb学习——Servlet相关的接口和类 摘要:本文主要学习了Servlet相关的接口和类. Servlet的接口和类 三种方式 实现Servlet有三种方式: 实现javax.servle ...

随机推荐

  1. Google Chrome 35 Released – Install on RHEL/CentOS 6 and Fedora 20-15

    Google Chrome is a freeware web browser developed by Google Inc. Google Chrome team proudly announce ...

  2. SecureCRT如何调整好看的黄色

    1.常规 →默认会话→编辑默认编辑→白黑 字体为console 2.全局选项 ANSI颜色有一个 把黄色 拖过去即可

  3. 重启nginx后丢失nginx.pid的解决方法(转)

    一,nginx的停止操作 停止操作是通过向nginx进程发送信号来实现的.步骤1:查询nginx主进程号 ps -ef | grep nginx 在进程列表里 面找master进程,它的编号就是主进程 ...

  4. Oracle ODBC无Oracle连接驱动

    .下载odbc驱动 需要下载两个东西 instantclient.zip instantclient.zip 下载地址:http:.html 解压放到同一个目录(无冲突) .将oracle数据库所在电 ...

  5. 键盘上所有键位的ascii值

    上次用的时候一直找,这次找到了,收藏起来. 0x1 鼠标左键 0x2 鼠标右键 0x3 CANCEL 键 0x4 鼠标中键 0x8 BACKSPACE 键 0x9 TAB 键 0xC CLEAR 键 ...

  6. 删除数据库时提示数据库正在被使用,无法删除(Cannot drop database databasename because it is currently in use)的问题

    删除数据库时提示数据库正在被使用,无法删除(Cannot drop database databasename because it is currently in use)的问题   删除数据库时提 ...

  7. 《TCP/IP具体解释卷2:实现》笔记--IP的分片和重装

    IP首部内有三个字段实现分片和重装:标识字段(ip_id).标志字段(ip_off的3个高位比特)和偏移字段(ip_off的13个低位 比特).标志字段由3个1bit标志组成.比特0是保留的必须为0, ...

  8. curl测试Docker容器连通性

    通过curl来测试docker对外访问是否正常,这里测试Docker tomcat容器访问: [root@mysqlserver ~]# curl http://172.17.0.8:8080 < ...

  9. create table #temptable 临时表 和 declare @bianliang table ()表变量

    create table #temptable 临时表 和 declare @bianliang table ()表变量 在开发过程中,经常会遇到使用表变量和本地临时表的情况.下面是对二者的一个介绍: ...

  10. 【优才原创】Android的拖放机制

    优才网 [优才原创]Android的拖放机制 2016-04-18 优才学院 优才网 一.拖放机制概述 ² 拖放操作是手指触摸屏幕上的某一对象.然后拖动该对象.最后在屏幕的某个位置释放该对象并运行某种 ...