javax.servlet.ServletContext set/getAttribute线程安全吗? [英] Is javax.servlet.ServletContext set/getAttribute thread safe?

查看:88
本文介绍了javax.servlet.ServletContext set/getAttribute线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

必须在javax.servlet.ServletContext中使用setAttribute()getAttribute(String),我无法在并发访问中找到有关预期行为的任何信息.但是,这些操作很可能由不同的线程调用.

Having to use setAttribute() and getAttribute(String) in javax.servlet.ServletContext, I cannot find any information on the intended behavoir with concurrent access. However, these operations may very well be called by different threads.

servlet可以按名称将对象属性绑定到上下文中.任何 绑定到上下文中的属性可用于任何其他servlet 是同一Web应用程序的一部分.

A servlet can bind an object attribute into the context by name. Any attribute bound into a context is available to any other servlet that is part of the same Web application.

但是,没有有关这些操作的并发行为的信息.浏览源代码显示它是作为 ConcurrentHashMap ,从而使其具有线程安全性.

However, there is no information on concurrency behavior of these operations. A look into the source code of Apache Tomcat reveals that it is implemented as a ConcurrentHashMap, thus making it effectively thread-safe.

我的问题是,我应该始终将这些操作视为不是线程安全的,并让应用程序处理同步吗?还是我缺少一些信息?

My question is, should I always treat these operations as not thread-safe and have the application handle the synchronisation, or is there a piece of information that I am missing?

推荐答案

您可以放心地假设可以在不同步任何内容的情况下调用getAttribute和setAttribute,但是您应该使在此存储的对象具有线程安全性(最简单的存储方式是那是一成不变的).注释中链接的问题是关于在ServletContext中存储一个可变对象,在这种情况下,使用该对象的线程需要首先获取其锁(接受的答案解释).

You can safely assume you can call getAttribute and setAttribute without synchronizing on anything, but you should make the objects you store there threadsafe (the easiest way being to store things that are immutable). The question linked in the comments is about storing a mutable object in the servletContext, in which case threads using it need to acquire its lock first (which the accepted answer explains).

没有详细说明. 实践中的Java并发部分4.5.1解释模糊文档中对此进行了介绍:

There's not a spelled-out requirement. This is covered in Java Concurrency in Practice, section 4.5.1 Interpreting Vague Documentation:

您将不得不猜测.提高您的猜测质量的一种方法是从将要实施该规范的人员(例如容器或数据库供应商)的角度来解释该规范,而不是仅仅使用它的人员. Servlet总是从容器管理的线程中调用,可以安全地假设,如果有多个这样的线程,则容器知道这一点. Servlet容器使某些为多个Servlet提供服务的对象可用,例如HttpSession或ServletContext.因此,servlet容器应该期望并发地访问这些对象,因为它创建了多个线程并从它们中调用了诸如Servlet.service之类的方法,可以合理地期望它们访问ServletContext.

You are going to have to guess. One way to improve the quality of your guess is to interpret the specification from the perspective of someone who will implement it (such as a container or database vendor), as opposed to someone who will merely use it. Servlets are always called from a container-managed thread, and it is safe to assume that if there is more than one such thread, the container knows this. The servlet container makes available certain objects that provide service to multiple servlets, such as HttpSession or ServletContext. So the servlet container should expect to have these objects accessed concurrently, since it has created multiple threads and called methods like Servlet.service from them that could reasonably be expected to access the ServletContext.

由于无法想象在这些对象中有用的单线程上下文,因此即使规范未明确要求它们也必须假定它们已成为线程安全的.此外,如果他们需要客户端锁定,则客户端代码应在什么锁定上同步?该文档没有说,而且看起来很荒谬.规范和官方教程中的示例进一步支持了这种合理的假设",这些示例显示了如何访问ServletContext或HttpSession且不使用任何客户端同步.

Since it is impossible to imagine a single-threaded context in which these objects would be useful, one has to assume that they have been made thread-safe, even though the specification does not explicitly require this. Besides, if they required client-side locking, on what lock should the client code synchronize? The documentation doesn't say, and it seems absurd to guess. This "reasonable assumption" is further bolstered by the examples in the specification and official tutorials that show how to access ServletContext or HttpSession and do not use any client-side synchronization.

另一方面,放置在ServletContext或HttpSession中具有setAttribute的对象归Web应用程序所有,而不是Servlet容器. Servlet规范没有建议任何用于协调对共享属性的并发访问的机制.因此,容器代表Web应用程序存储的属性应该是线程安全的或有效不变的.如果所有容器都代表Web应用程序存储了这些属性,那么另一种选择是确保从Servlet应用程序代码访问它们时,它们始终受到锁的保护.但是因为容器可能出于复制或钝化目的而要序列化HttpSession中的对象,并且servlet容器可能无法知道您的锁定协议,所以应该使它们成为线程安全的.

On the other hand, the objects placed in the ServletContext or HttpSession with setAttribute are owned by the web application, not the servlet container. The servlet specification does not suggest any mechanism for coordinating concurrent access to shared attributes. So attributes stored by the container on behalf of the web application should be thread-safe or effectively immutable. If all the container did was store these attributes on behalf of the web application, another option would be to ensure that they are consistently guarded by a lock when accessed from servlet application code. But because the container may want to serialize objects in the HttpSession for replication or passivation purposes, and the servlet container can't possibly know your locking protocol, you should make them thread-safe.

这篇关于javax.servlet.ServletContext set/getAttribute线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆