假设,我有一个包含大量servlet的web服务器。对于在这些servlet之间传递的信息,我设置了会话和实例变量。
现在,如果2个或更多用户向这个服务器发送请求,那么会话变量会发生什么变化? 它们对所有用户都是通用的,还是对每个用户都是不同的? 如果它们是不同的,那么服务器如何区分不同的用户?
还有一个类似的问题,如果有n个用户访问一个特定的servlet,那么这个servlet只在第一个用户第一次访问它时实例化,还是为所有用户分别实例化? 换句话说,实例变量会发生什么变化?
假设,我有一个包含大量servlet的web服务器。对于在这些servlet之间传递的信息,我设置了会话和实例变量。
现在,如果2个或更多用户向这个服务器发送请求,那么会话变量会发生什么变化? 它们对所有用户都是通用的,还是对每个用户都是不同的? 如果它们是不同的,那么服务器如何区分不同的用户?
还有一个类似的问题,如果有n个用户访问一个特定的servlet,那么这个servlet只在第一个用户第一次访问它时实例化,还是为所有用户分别实例化? 换句话说,实例变量会发生什么变化?
当前回答
当servlet容器(如Apache Tomcat)启动时,如果出现任何错误或在容器端控制台显示错误,它将从web.xml文件中读取(每个应用程序只有一个),否则,它将使用web.xml(因此将其命名为部署描述符)部署和加载所有web应用程序。
在servlet实例化阶段,servlet实例已经准备好了,但是它不能为客户端请求服务,因为它缺少两个信息: 1:上下文信息 2:初始配置信息
Servlet引擎创建servletConfig接口对象,其中封装了上述缺失的信息 servlet引擎通过提供servletConfig对象引用作为参数来调用servlet的init()。一旦init()完全执行,servlet就准备好为客户端请求服务了。
Q)在servlet的生命周期中,实例化和初始化发生了多少次?
A)只有一次(对于每个客户端请求都创建一个新线程) 只有一个servlet实例服务于任意数量的客户端请求,即服务一个客户端请求后服务器不会死亡。它等待其他客户端请求,即CGI(每个客户端请求都会创建一个新进程)的限制被servlet(内部servlet引擎创建线程)克服。
Q)会话概念是如何工作的?
A)每当在HttpServletRequest对象上调用getSession()时
步骤1:评估请求对象的传入会话ID。
第二步:如果ID不可用,则创建一个全新的HttpSession对象,并生成相应的会话ID(即HashTable)。会话ID存储在httpservlet响应对象中,HttpSession对象的引用返回给servlet (doGet/doPost)。
第三步:如果ID可用,没有创建全新的会话对象,则从请求对象中获取会话ID,以会话ID为键在会话集合中进行搜索。
一旦搜索成功,会话ID将存储到HttpServletResponse中,现有的会话对象引用将返回到UserDefineservlet的doGet()或doPost()。
注意:
1)当控制从servlet代码转移到客户端时,不要忘记会话对象是由servlet容器(即servlet引擎)保存的
2)多线程留给servlet开发人员去实现ie。,处理客户端的多个请求,不用担心多线程代码
简称:
A servlet is created when the application starts (it is deployed on the servlet container) or when it is first accessed (depending on the load-on-startup setting) when the servlet is instantiated, the init() method of the servlet is called then the servlet (its one and only instance) handles all requests (its service() method being called by multiple threads). That's why it is not advisable to have any synchronization in it, and you should avoid instance variables of the servlet when the application is undeployed (the servlet container stops), the destroy() method is called.
其他回答
Session in Java servlets is the same as session in other languages such as PHP. It is unique to the user. The server can keep track of it in different ways such as cookies, url rewriting etc. This Java doc article explains it in the context of Java servlets and indicates that exactly how session is maintained is an implementation detail left to the designers of the server. The specification only stipulates that it must be maintained as unique to a user across multiple connections to the server. Check out this article from Oracle for more information about both of your questions.
这里有一个关于如何在servlet中使用session的优秀教程。这里有来自Sun的一章关于Java servlet,它们是什么以及如何使用它们。在这两篇文章之间,你应该能够回答你所有的问题。
塞申斯是克里斯·汤普森说的。
实例化——当容器接收到第一个映射到servlet的请求时,servlet被实例化(除非servlet被配置为在web.xml中使用<load-on-startup>元素在启动时加载)。使用相同的实例为后续请求提供服务。
不。servlet不是线程安全的
这允许一次访问多个线程
如果你想让它成为线程安全的Servlet,你可以去
实现SingleThreadInterface(我) 哪个是空白界面有没有
方法
或者我们可以使用同步方法
利用synchronized可以使整个服务方法实现同步化
关键字前面的方法
例如::
public Synchronized class service(ServletRequest request,ServletResponse response)throws ServletException,IOException
或者我们可以把代码的put块放在Synchronized块中
例如::
Synchronized(Object)
{
----Instructions-----
}
我觉得Synchronized块比整个方法更好
同步
当servlet容器(如Apache Tomcat)启动时,如果出现任何错误或在容器端控制台显示错误,它将从web.xml文件中读取(每个应用程序只有一个),否则,它将使用web.xml(因此将其命名为部署描述符)部署和加载所有web应用程序。
在servlet实例化阶段,servlet实例已经准备好了,但是它不能为客户端请求服务,因为它缺少两个信息: 1:上下文信息 2:初始配置信息
Servlet引擎创建servletConfig接口对象,其中封装了上述缺失的信息 servlet引擎通过提供servletConfig对象引用作为参数来调用servlet的init()。一旦init()完全执行,servlet就准备好为客户端请求服务了。
Q)在servlet的生命周期中,实例化和初始化发生了多少次?
A)只有一次(对于每个客户端请求都创建一个新线程) 只有一个servlet实例服务于任意数量的客户端请求,即服务一个客户端请求后服务器不会死亡。它等待其他客户端请求,即CGI(每个客户端请求都会创建一个新进程)的限制被servlet(内部servlet引擎创建线程)克服。
Q)会话概念是如何工作的?
A)每当在HttpServletRequest对象上调用getSession()时
步骤1:评估请求对象的传入会话ID。
第二步:如果ID不可用,则创建一个全新的HttpSession对象,并生成相应的会话ID(即HashTable)。会话ID存储在httpservlet响应对象中,HttpSession对象的引用返回给servlet (doGet/doPost)。
第三步:如果ID可用,没有创建全新的会话对象,则从请求对象中获取会话ID,以会话ID为键在会话集合中进行搜索。
一旦搜索成功,会话ID将存储到HttpServletResponse中,现有的会话对象引用将返回到UserDefineservlet的doGet()或doPost()。
注意:
1)当控制从servlet代码转移到客户端时,不要忘记会话对象是由servlet容器(即servlet引擎)保存的
2)多线程留给servlet开发人员去实现ie。,处理客户端的多个请求,不用担心多线程代码
简称:
A servlet is created when the application starts (it is deployed on the servlet container) or when it is first accessed (depending on the load-on-startup setting) when the servlet is instantiated, the init() method of the servlet is called then the servlet (its one and only instance) handles all requests (its service() method being called by multiple threads). That's why it is not advisable to have any synchronization in it, and you should avoid instance variables of the servlet when the application is undeployed (the servlet container stops), the destroy() method is called.
Servlet规范JSR-315明确定义了服务(以及doGet、doPost、doPut等)方法中的web容器行为(2.3.3.1多线程问题,第9页):
A servlet container may send concurrent requests through the service method of the servlet. To handle the requests, the Servlet Developer must make adequate provisions for concurrent processing with multiple threads in the service method. Although it is not recommended, an alternative for the Developer is to implement the SingleThreadModel interface which requires the container to guarantee that there is only one request thread at a time in the service method. A servlet container may satisfy this requirement by serializing requests on a servlet, or by maintaining a pool of servlet instances. If the servlet is part of a Web application that has been marked as distributable, the container may maintain a pool of servlet instances in each JVM that the application is distributed across. For servlets not implementing the SingleThreadModel interface, if the service method (or methods such as doGet or doPost which are dispatched to the service method of the HttpServlet abstract class) has been defined with the synchronized keyword, the servlet container cannot use the instance pool approach, but must serialize requests through it. It is strongly recommended that Developers not synchronize the service method (or methods dispatched to it) in these circumstances because of detrimental effects on performance