您可以放心地假设您可以调用getAttribute和setAttribute而不对任何内容进行同步,但是您应该使在那里存储的对象成为线程安全的(最简单的方法是存储不可变的东西)。注释中链接的问题是关于在ServletContext中存储一个可变对象,在这种情况下,使用该对象的线程需要首先获取其锁(已接受的答案对此进行了解释)。
没有明确的要求。《 Java并发实践 》第4.5.1节“解释模糊文档”中对此进行了介绍:
您将不得不猜测。提高您的猜测质量的一种方法是从将要实施该规范的人员(例如容器或数据库供应商)的角度来解释该规范,而不是仅仅使用它的人员。Servlet总是从容器管理的线程中调用,可以安全地假设,如果有多个这样的线程,则容器知道这一点。Servlet容器使某些为多个Servlet提供服务的对象可用,例如HttpSession或ServletContext。因此,Servlet容器应该期望并发地访问这些对象,因为它创建了多个线程并从它们中调用了诸如Servlet.service之类的方法,可以合理地期望它们访问ServletContext。
由于无法想象在这些对象中有用的单线程上下文,因此即使规范没有明确要求它们也必须假定它们已成为线程安全的。此外,如果他们需要客户端锁定,则客户端代码应在什么锁定上同步?该文档没有说,而且看起来很荒谬。规范和官方教程中的示例进一步支持了这种“合理的假设”,这些示例显示了如何访问ServletContext或HttpSession而不使用任何客户端同步。
另一方面,通过setAttribute放置在ServletContext或HttpSession中的对象归Web应用程序所有,而不是Servlet容器。Servlet规范没有建议任何用于协调对共享属性的并发访问的机制。因此,容器代表Web应用程序存储的属性应该是线程安全的或有效不变的。如果所有容器都代表Web应用程序存储了这些属性,那么另一种选择是确保从Servlet应用程序代码访问它们时,它们始终受到锁的保护。但是,由于容器可能要序列化HttpSession中的对象以进行复制或钝化,并且servlet容器可能无法知道您的锁定协议,因此应使它们成为线程安全的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)