`

Servlet容器之安全多线程问题

    博客分类:
  • JSP
阅读更多

原文地址:http://developer.51cto.com/art/200907/133794.htm

 

    Servlet容器如何实现多线程。其安全的方面又是如何呢?那么本文将就Servlet容器实现多线程给你做简单的介绍。

     

    一,Servlet容器如何同时处理多个请求。

    Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求。

    线程池实际上是等待执行代码的一组线程叫做工作者线程(WorkerThread),Servlet容器使用一个调度线程来管理工作者线程(DispatcherThread)。

    当容器收到一个访问Servlet的请求,调度者线程从线程池中选出一个工作者线程,将请求传递给该线程,然后由该线程来执行Servlet的service方法。

    当这个线程正在执行的时候,容器收到另外一个请求,调度者线程将从池中选出另外一个工作者线程来服务新的请求,容器并不关系这个请求是否访问的是同一个Servlet还是另外一个Servlet。

    当容器同时收到对同一Servlet的多个请求,那这个Servlet的service方法将在多线程中并发的执行。

    二,Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间。对于Tomcat可以在server.xml中通过<Connector>元素设置线程池中线程的数目。

    就实现来说:

    调度者线程类所担负的责任如其名字,该类的责任是调度线程,只需要利用自己的属性完成自己的责任。所以该类是承担了责任的,并且该类的责任又集中到唯一的单体对象中。

    而其他对象又依赖于该特定对象所承担的责任,我们就需要得到该特定对象。那该类就是一个单例模式的实现了。

    三,如何开发线程安全的Servlet

    1,变量的线程安全:这里的变量指字段和共享数据(如表单参数值)。

    a,将参数变量本地化。多线程并不共享局部变量.所以我们要尽可能的在servlet中使用局部变量。

    例如:

  1. Stringuser="";  
  2. user=request.getParameter("user"); 

b,使用同步块Synchronized,防止可能异步调用的代码块。这意味着线程需要排队处理。

在使用同板块的时候要尽可能的缩小同步代码的范围,不要直接在sevice方法和响应方法上使用同步,这样会严重影响性能。

2,属性的线程安全:ServletContext,HttpSession,ServletRequest对象中属性

ServletContext:(线程是不安全的)

ServletContext是可以多线程同时读/写属性的,线程是不安全的。要对属性的读写进行同步处理或者进行深度Clone()。

所以在Servlet上下文中尽可能少量保存会被修改(写)的数据,可以采取其他方式在多个Servlet中共享,比方我们可以使用单例模式来处理共享数据。

HttpSession:(线程是不安全的)

HttpSession对象在用户会话期间存在,只能在处理属于同一个Session的请求的线程中被访问,因此Session对象的属性访问理论上是线程安全的。

当用户打开多个同属于一个进程的浏览器窗口,在这些窗口的访问属于同一个Session,会出现多次请求,需要多个工作线程来处理请求,可能造成同时多线程读写属性。

这时我们需要对属性的读写进行同步处理:使用同步块Synchronized和使用读/写器来解决。

ServletRequest:(线程是安全的)

对于每一个请求,由一个工作线程来执行,都会创建有一个新的ServletRequest对象,所以ServletRequest对象只能在一个线程中被访问。ServletRequest是线程安全的。

注意:ServletRequest对象在service方法的范围内是有效的,不要试图在service方法结束后仍然保存请求对象的引用。

3,使用同步的集合类:

使用Vector代替ArrayList,使用Hashtable代替HashMap。

4,不要在Servlet中创建自己的线程来完成某个功能。

Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化,出现多线程安全问题。

5,在多个servlet中对外部对象(比方文件)进行修改操作一定要加锁,做到互斥的访问。

四,SingleThreadModel接口

javax.servlet.SingleThreadModel接口是一个标识接口,如果一个Servlet实现了这个接口,那Servlet容器将保证在一个时刻仅有一个线程可以在给定的servlet实例的service方法中执行。将其他所有请求进行排队。

服务器可以使用多个实例来处理请求,代替单个实例的请求排队带来的效益问题。服务器创建一个Servlet类的多个Servlet实例组成的实例池,对于每个请求分配Servlet实例进行响应处理,之后放回到实例池中等待下此请求。这样就造成并发访问的问题。

此时,局部变量(字段)也是安全的,但对于全局变量和共享数据是不安全的,需要进行同步处理。而对于这样多实例的情况SingleThreadModel接口并不能解决并发访问问题。

SingleThreadModel接口在servlet规范中已经被废弃了。

分享到:
评论

相关推荐

    异步servlet上传文件,解决网速慢以及大文件,耗完线程问题

    假如一个场景,用户上传文件,某些用户网速较慢,同时存在100个这样的用户,如果BIO且最大线程设为100会导致线程用完。...本实例采用tomcat8作为容器,开启异步servlet读写事件,解决高并发IO传输问题。

    JSP/Servlet Java面试逻辑题

    5、如何现实servlet的单线程模式★★ 答:&lt;%@page isThreadSafe=false%&gt; 面试中会遇到! 6、页面间对象传递的方法 答:request,session,application,cookie等 7、JSP和Servlet有哪些相同点和不同点,他们...

    java-servlet-api.doc

    在多线程的环境下,Servlet必须能处理许多同时发生的请求。例外的情况是这个Servlet执行了SingleThreadModel接口,如果是那样的话,Servlet只能同时处理一个请求。 Servlet依照Servlet引擎的映射来响应客户端的请求...

    Java™ Servlet 规范.

    1.2 什么是 Servlet 容器?...............................................................................................................................13 1.3 例子 .......................................

    教师信息管理系统源代码

    jsp+select综合使用,主要是对教师信息实现增删改查的功能。 当用户访问一个JSP页面时,会向一个Servlet容器...如果用户有多个请求,则容器会建立多个线程处理多个请求;容器执行字节码文件(包括调用的servlet:form)

    tomcat中Servlet对象池介绍及如何使用

    如下图,这种情况下,Wrapper容器只会通过反射实例化一个Servlet对象,对应此Servlet的所有客户端请求都会共用此Servlet对象,而对于多个客户端请求tomcat会使用多线程处理,所以应该保证此Servlet对象的线程安全,...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    11.1 多线程的servlet模型 350 11.2 线程安全的servlet 351 11.2.1 变量的线程安全 351 11.2.2 属性的线程安全 360 11.3 singlethreadmodel接口 362 11.4 小结 363 11.5 思考题 363 第3部分 jsp篇 第12章 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    11.1 多线程的servlet模型 350 11.2 线程安全的servlet 351 11.2.1 变量的线程安全 351 11.2.2 属性的线程安全 360 11.3 singlethreadmodel接口 362 11.4 小结 363 11.5 思考题 363 第3部分 jsp篇 第12章 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    11.1 多线程的servlet模型 350 11.2 线程安全的servlet 351 11.2.1 变量的线程安全 351 11.2.2 属性的线程安全 360 11.3 singlethreadmodel接口 362 11.4 小结 363 11.5 思考题 363 第3部分 jsp篇 第12章 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    11.1 多线程的servlet模型 350 11.2 线程安全的servlet 351 11.2.1 变量的线程安全 351 11.2.2 属性的线程安全 360 11.3 singlethreadmodel接口 362 11.4 小结 363 11.5 思考题 363 第3部分 jsp篇 第12章 ...

    Servlet3.1规范(最终版) PDF

    13 什么是Servlet容器?...............................................................................................................................13 例子...............................................

    android-http-server:带有示例Android应用程序的Java中Web服务器和servlet容器的完整零依赖实现

    Android HTTP服务器小型但功能强大的多线程Web服务器,完全用Java SE编写,然后移植到Android。 该服务器实现大多数HTTP 1.1规范,并提供可用于处理动态页面的自定义servlet API。 Servlet API是在官方javax.servlet...

    Javaweb面试题.docx

    与cgi 的区别在于servlet 处于服务器进程中,它通过多线程方式运行其service 方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI 对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于...

    免费超全面的Java基础类型,容器,并发,IO流,面向对象,Web编程等代码总结

    多线程并发访问,同步控制 线程间通信,等待/通知机制 锁锁机制,API详解 Fork/Join 框架机制详解 Executor线程池框架简介 面向对象 泛型机制与反射原理 Proxy动态代理机制详解 从整体上观察对象 网络开发 Servlet...

    2023Java高频面试题

    多线程编程:线程的基本概念、线程同步、线程安全、死锁等问题。 JDBC:Java与数据库的交互,连接池的使用等。 Spring框架:Spring框架的基础概念、IOC容器、AOP等。 Hibernate框架:Hibernate框架的基础概念、ORM...

    JAVA笔试题目集合

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

    202302-Java集合容器面试题(2023最新版)思维导图.zip

    - 多线程编程 2. 数据库: - 熟悉SQL语言 - 了解关系型数据库和非关系型数据库 - 数据库连接池 - 数据库事务 3. Spring框架: - Spring Boot - Spring MVC - Spring Data - Spring Security - Spring...

    从入门到精通38万字超详细的Java面试题&amp;八股文&amp;知识点全面汇总

    ​ 1.9多线程面试题 ​ 1.10MyBatis面试题 ​ 1.11Spring MVC面试题 ​ 1.12Spring Boot面试题 ​ 1.13Spring Cloud面试题 2、中间件面试题 3、数据库&SQL面试题 4、前端面试题 ​ 4.1CSS面试题 ​ 4.2HTML面试题 ​...

    Struts1与Struts2本质区别

    Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。 3 Servlet依赖方面的对比:Struts 1 Action依赖于Servlet API,因为Struts 1 Action的execute方法中有HttpServletRequest和...

Global site tag (gtag.js) - Google Analytics