1是单例还是多例
如果一个Servlet没有被部署在分布式的环境中,一般web.xml中声明的一个Servlet只对应一个实例。
而如果一个Servlet实现了SingleThreadModel接口,就会被初始化多个实例。
参考文章:https://www.cnblogs.com/softidea/p/7245899.html
2如何保证单例多线程的线程安全
1同步对线程共享数据的操作
2不使用实例变量
将实例变量改成局部变量
几点规则:
1,变量的线程安全:这里的变量指字段和共享数据(如表单参数值)。 a,将 参数变量 本地化。多线程并不共享局部变量.所以我们要尽可能的在servlet中使用局部变量。 例如:String user = ""; 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方法结束后仍然保存请求对象的引用。
4,不要在Servlet中创建自己的线程来完成某个功能。 Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化,出现多线程安全问题。
5,在多个servlet中对外部对象(比方文件)进行修改操作一定要加锁,做到互斥的访问。
6,javax.servlet.SingleThreadModel接口是一个标识接口,如果一个Servlet实现了这个接口,那Servlet容器将保证在一个时刻仅有一个线程可以在给定的servlet实例的service方法中执行。将其他所有请求进行排队。
参考文章:https://blog.youkuaiyun.com/xiaojiahao_kevin/article/details/51781946
3框架的单例多例
Spring的Ioc容器管理的bean 默认是单实例的.
spring mvc的controller也是单例。因此开发时要求必须是线程安全的
Struts2的Action是原型,非单实例的;会对每一个请求,产生一个Action的实例来处理。
参考文章:https://blog.youkuaiyun.com/xiaojiahao_kevin/article/details/51781946
4servlet的生命周期
1web服务器启动时加载并实例化,容器运行其init()方法初始化
2请求到达运行service方法
3service运行请求对应的doXXX(doGet,doPost)方法;
4服务器销毁实例,运行其destory方法;
5servlet容器,web服务器,应用服务器
三个概念的理解: Servlet容器<Web容器<应用服务器? Servlet容器的主要任务就是管理Servlet的生命周期; Web容器也称之为web服务器,主要任务就是管理和部署web应用的; 应用服务器的功能非常强大,不仅可以管理和部署web应用,也可以部署EJB应用,实现容器管理的事务等等。。。 Web服务器就是跟基于HTTP的请求打交道,而EJB容器更多是跟数据库,事务管理等服务接口交互,所以应用服务器的功能是很多的。 常见的web服务器就是Tomcat,但Tomcat同样也是Servlet服务器; 常见的应用服务器有WebLogic,WebSphere,但都是收费的; 没有Servlet容器,可以用Web容器直接访问静态Html页面,比如安装了apache等;如果需要显示Jsp/Servlet,就需要安装一个Servlet容器;但是光有servlet容器也是不够的,它需要被解析为html显示,所以仍需要一个web容器;所以,我们常把web容器和Servlet容器视为一体,因为他们两个容器都有对方的功能实现了,都没有独立的存在了,比如tomcat!
servlet生命周期由servlet容器管理。