简述Servlet多线程_Tomcat, WebLogic及J2EE讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Tomcat, WebLogic及J2EE讨论区 »
总帖数
2
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2804 | 回复: 1   主题: 简述Servlet多线程        下一篇 
nengqiang.wang
注册用户
等级:中校
经验:1658
发帖:34
精华:0
注册:1970-1-1
状态:离线
发送短消息息给nengqiang.wang 加好友    发送短消息息给nengqiang.wang 发消息
发表于: IP:您无权察看 2015-8-11 17:50:18 | [全部帖] [楼主帖] 楼主

1 Servlet

的生命周期

 Servlet 生命周期:Servlet 加载--->实例化--->服务--->销毁。

1)init():在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。

2)service():它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。

3)destroy(): 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。

2 servlet

容器如何同时处理多个请求

  Servlet

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

线程池实际上是等待执行代码的一组线程叫做工作者线程(Worker Thread)Servlet容器使用一个调度线程来管理工作者线程(Dispatcher Thread)。当容器收到一个访问Servlet的请求,调度者线程从线程池中选出一个工作者线程,将请求传递给该线程,然后由该线程来执行Servletservice方法。当这个线程正在执行的时候,容器收到另外一个请求,调度者线程将从池中选出另外一个工作者线程来服务新的请求,容器并不关心这个请求是否访问的是同一个Servlet还是另外一个Servlet。当容器同时收到对同一Servlet的多个请求,那这个Servletservice方法将在多线程中并发的执行。Servlet多线程体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。

     Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间。当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。所以在用Servlet构建的Web应用时如果不注意线程安全的问题,会使所写的Servlet程序有难以发现的错误。出现这些错误的原因大多是因为servlet中实例变量使用不当。

3 JMM(Java Memory Model)


  Java的内存模型JMMJava Memory ModelJMM主要是为了规定了线程和内存之间的一些关系。根据JMM的设计,系统存在一个主内存(Main Memory)Java中所有实例变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存由缓存和堆栈两部分组成,缓存中保存的是主存中变量的拷贝,缓存可能并不总和主存同步,也就是缓存中变量的修改可能没有立刻写到主存中;堆栈中保存的是线程的局部变量,线程之间无法相互直接访问堆栈中的变量。

开发线程安全的Servlet

(1)避免使用实例变量   

  多线程并不共享局部变量.所以我们要尽可能的在servlet中使用局部变量,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。

2)使用同步块Synchronized

 同步块Synchronized防止可能异步调用的代码块。这意味着线程需要排队处理,在使用同板块的时候要尽可能的缩小同步代码的范围,不要直接在sevice方法和响应方法上使用同步,这样会严重影响性能。

3)使用同步集合类

  使用Vector代替ArrayList,使用Hashtable代替HashMapVectorHashtable虽然是线程安全的但性能较低。

4)不要再servlet中创建自己的线程来完成某些功能

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

5)实现SingleThreadModel 接口

该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。

如果servlet实现了该接口,会确保不会有两个线程同时执行servletservice方法。 servlet容器通过同步化访问servlet的单实例来保证,也可以通过维持servlet的实例池,对于新的请求会分配给一个空闲的servlet

SingleThreadModel不会解决所有的线程安全隐患。 例如,会话属性和静态变量仍然可以被多线程的多请求同时访问,即便使用了SingleThreadModel servlet。该接口在Servlet API 2.4中不推荐使用。



人们都向往和寻找快乐,其实快乐就是一种心情,秘密隐藏于人的心中。快乐从不曾远离我们,而是我们远离了快乐。原本单纯的心,一旦复杂起来,快乐和幸福就 会远离而去,烦恼和忧愁就会随之而来。






赞(0)    操作        顶端 
arcona
注册用户
等级:少校
经验:1100
发帖:10
精华:0
注册:2015-6-1
状态:离线
发送短消息息给arcona 加好友    发送短消息息给arcona 发消息
发表于: IP:您无权察看 2016-8-2 9:17:56 | [全部帖] [楼主帖] 2  楼

实用,感谢分享~



赞(0)    操作        顶端 
总帖数
2
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论