我想创建一个Thread安全的JSP页面。可以在Servlet中实现SingleThreadModel接口,但我不知道如何在JSP页面中这样做。
答案 0 :(得分:9)
理论上,JSP页面可以通过isThreadSafe
页面指令属性表示为线程安全。设置值false将使容器同步对页面级对象的访问(而不是对会话和应用程序作用域对象或任何其他类型的对象)。显然,开发人员仍有责任确保同步访问线程不安全的代码区域。
Morevoer,在Servlet规范版本2.4中也不推荐使用SingleThreadModel接口。 SingleThreadModel接口用于在JSP中实现假设的线程安全性 - 生成的servlet类将为使用threadsafe属性的JSP实现SingleThreadModel。规范本身概述了不推荐使用接口的原因:
SRV.2.2.1关于单线程模型的注释
使用SingleThreadModel 接口保证只有一个 一次执行的线程将在a中执行 给出servlet实例的服务 方法。重要的是要注意到这一点 此保证仅适用于每个 servlet实例,因为容器 可以选择汇集这些对象。 可以访问更多的对象 一次只有一个servlet实例, 例如HttpSession的实例,可能 可以在任何特定时间到达 多个servlet,包括那些 实现SingleThreadModel。
建议开发人员 采取其他方式解决这些问题 问题而不是实现这一点 界面,如避免使用 实例变量或 同步代码块 访问这些资源。该 SingleThreadModel接口是 在此版本中弃用 说明书
答案 1 :(得分:5)
首先简短回答<%@ page isThreadSafe =“false”%>
答案越长,不要这样做。
你需要在这里明确你的目标。你没有通过使用SingleThreadModel使servlet成为真正的线程安全的,而是你已经设置好了,所以一次只有一个线程可以进入你的servlet。 Presullly你会这样做,因为Servlet代码是不线程安全,也就是说,如果有多个线程获取代码,那么会发生不好的事情。
这意味着我在servlet代码中有这样的东西:
doGet(/*etc/*){
// ... stuff
someExistingUnsafeClass.doSomething();
// .. more stuff
}
毕竟,你的serlvet代码本身不能是线程不安全的吗?你会解决它,对吗?那么它必须是一些线程不安全的遗留代码吗?
如果是这种情况,您的JSP需要使用现有的遗留代码,在JSP的某个地方,您会调用不安全的东西:
<%
someExistingUnsafeClass.doSomething();
%>
所以你只需要保护这个不安全的电话:
<%
synchronized(this){
someExistingUnsafeClass.doSomething();
};
%>
允许大量JSP正常运行将会更好地运行。
我还应该说,如果你将应用程序构建为MVC,那么从控制器调用所有线程不安全的代码,并且视图(JSP)永远不需要是不安全的。
答案 2 :(得分:3)
在JSP页面中没有任何状态信息。 (没有实例变量,可以根据不同的请求进行更改)。如果JSP或servlet中没有任何状态,则它们是线程安全的
答案 3 :(得分:1)
用JSP讨论线程安全是错误的 - JSP是一种视图技术,它只显示结果 - 它不进行任何处理。 (可以进行处理,但一定不能)
servlet的线程安全是通过在servlet中包含 no 私有字段来实现的 - servlet实例是整个容器的一个,每个请求都是一个调用service(..)
方法的新线程
在你的情况下,你应该准确地指出“线程安全”的意思 - 即你期望失败的是什么。
答案 4 :(得分:1)
在JSP中,只需在scriplets中使用变量,您就可以确信它们是线程安全的,因为它们将被转换为service()
中的局部变量。
答案 5 :(得分:0)
你没有。
JSP基本上是servlet中的单个方法。您可能已经知道,方法是线程安全的,即两个线程同时调用同一对象的相同方法的意义,将在其自己的堆栈中执行每个方法。
所以,你真的不需要创建一个线程安全的JSP,因为它已经是贸易安全的。
如果在JSP中声明变量a
,则没有办法,另一个请求会看到该变量。
您必须注意的是,放入会话的对象,或者多个线程可以同时访问上下文,或者几乎不是线程安全的代码。那么你必须同步或处理的是 那些对象! ,而不是它自己的JSP页面。