假设,我有一个包含大量servlet的web服务器。对于在这些servlet之间传递的信息,我设置了会话和实例变量。

现在,如果2个或更多用户向这个服务器发送请求,那么会话变量会发生什么变化? 它们对所有用户都是通用的,还是对每个用户都是不同的? 如果它们是不同的,那么服务器如何区分不同的用户?

还有一个类似的问题,如果有n个用户访问一个特定的servlet,那么这个servlet只在第一个用户第一次访问它时实例化,还是为所有用户分别实例化? 换句话说,实例变量会发生什么变化?


当前回答

会话

简而言之:web服务器在每个访问者第一次访问时向其发出唯一标识符。访客必须带回来这个ID,以便下次来的时候能被认出来。这个标识符还允许服务器正确地将一个会话拥有的对象与另一个会话拥有的对象隔离。

Servlet实例化

如果load-on-startup为false:

如果load-on-startup为true:

一旦他进入服务模式并处于最佳状态,同一个servlet将处理来自所有其他客户机的请求。

为什么每个客户端有一个实例不是一个好主意?想想看:你会为每一份披萨订单雇一个送披萨的吗?那样做的话,你很快就会破产。

但这也有一个小风险。记住:这个家伙把所有的订单信息都放在他的口袋里:因此,如果您不注意servlet上的线程安全,他可能最终会向某个客户端发出错误的订单。

其他回答

会话

简而言之:web服务器在每个访问者第一次访问时向其发出唯一标识符。访客必须带回来这个ID,以便下次来的时候能被认出来。这个标识符还允许服务器正确地将一个会话拥有的对象与另一个会话拥有的对象隔离。

Servlet实例化

如果load-on-startup为false:

如果load-on-startup为true:

一旦他进入服务模式并处于最佳状态,同一个servlet将处理来自所有其他客户机的请求。

为什么每个客户端有一个实例不是一个好主意?想想看:你会为每一份披萨订单雇一个送披萨的吗?那样做的话,你很快就会破产。

但这也有一个小风险。记住:这个家伙把所有的订单信息都放在他的口袋里:因此,如果您不注意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规范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

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,它们是什么以及如何使用它们。在这两篇文章之间,你应该能够回答你所有的问题。