如何创建Thread安全JSP页面

我想创建一个Thread安全的JSP页面。 通过实现SingleThreadModel接口可以在Servlet中实现,但我不知道如何在JSP页面中执行它。

从理论上讲,JSP页面可以通过isThreadSafe页面指​​令属性表示为线程安全。 设置值false将使容器同步对页面级对象的访问(而不是对会话和应用程序作用域对象或任何其他类型的对象)。 显然,开发人员仍有责任确保同步访问线程不安全的代码区域。

Morevoer,SingleThreadModel接口也在Servlet Specification 2.4版中被弃用。 SingleThreadModel接口用于在JSP中实现假定的线程安全性 – 生成的servlet类将为使用threadsafe属性的JSP实现SingleThreadModel。 规范本身概述了不推荐使用该接口的原因:

SRV.2.2.1关于单线程模型的注释

使用SingleThreadModel接口可确保一次只有一个线程将在给定的servlet实例的服务方法中执行。 重要的是要注意,此保证仅适用于每个servlet实例,因为容器可以选择池化这些对象。 一次可以访问多个servlet实例的对象(例如HttpSession的实例)可以在任何特定时间到达多个servlet,包括那些实现SingleThreadModel的servlet。

建议开发人员采取其他方法来解决这些问题而不是实现此接口,例如避免使用实例变量或同步访问这些资源的代码块。 在此版本的规范中不推荐使用SingleThreadModel接口。

首先简短回答<%@ page isThreadSafe =“false”%>

更长的答案是不要那样做。

你需要在这里非常清楚你的目标。 你没有通过使用SingleThreadModel使servlet真正成为线程安全的,而是你已经设置好了,所以一次只有一个线程可以进入你的servlet。 假设你会这样做,因为Servlet代码不是线程安全的,也就是说,如果不止一个线程获取代码,那么事情就会发生。

这对我来说意味着你在servlet代码中有这样的东西:

  doGet(/*etc/*){ // ... stuff someExistingUnsafeClass.doSomething(); // .. more stuff } 

毕竟,你的serlvet代码本身不能是线程不安全的吗? 你会解决它,对吗? 所以它必须是一些线程不安全的遗留代码?

如果是这种情况,您的JSP需要使用现有的遗留代码,在JSP的某个地方,您会调用不安全的东西:

 <% someExistingUnsafeClass.doSomething(); %> 

所以你只需要保护这个不安全的电话:

 <% synchronized(this){ someExistingUnsafeClass.doSomething(); }; %> 

允许大量JSP正确运行线程会更好。

我还应该说,如果你将应用程序构建为MVC,那么从控制器调用所有线程不安全的代码,并且视图(JSP)永远不需要是不安全的。

在JSP页面中没有任何状态信息 。 (没有实例变量,可以根据不同的请求进行更改)。 如果JSP或servlet中没有任何状态,则它们是线程安全的

用JSP谈论线程安全是错误的 – JSP是一种视图技术,它只显示结果 – 它不进行任何处理。 (它可以做处理,但一定不能)

servlet的线程安全是通过在servlet中没有私有字段来实现的 – servlet实例是整个容器的一个,每个请求都是一个调用service(..)方法的新线程。

您应该在您的情况下准确指定“线程安全”的含义 – 即您期望失败的是什么。

在JSP中,只需在scriplets中使用变量,您就可以确信它们是线程安全的,因为它们将被转换为service()局部变量。

你没有。

JSP基本上是servlet中的单个方法。 您可能已经知道,方法是线程安全的,即两个线程同时调用同一对象的相同方法的意义,将在其自己的堆栈中执行每个方法。

所以,你真的不需要创建一个线程安全的JSP,因为它已经是贸易安全的。

如果在JSP中声明变量a ,则没有办法,另一个请求会看到该变量。

您必须注意的是,对象放入会话,或者上下文可能同时被多个线程访问,或者几乎不是线程安全的代码。 然后你必须同步或照顾的是那些对象! ,而不是它自己的JSP页面。