我希望创建一个线程安全的JSP页面。在Servlet中,通过实现SingleThreadModel接口可以实现,但我不知道如何在JSP页面中实现。
我希望创建一个线程安全的JSP页面。在Servlet中,通过实现SingleThreadModel接口可以实现,但我不知道如何在JSP页面中实现。
isThreadSafe
页面指令属性将JSP页面标识为线程安全。设置false的值,将使容器同步访问页面级别的对象(而不是会话和应用程序范围的对象或任何其他类型的对象)。显然,开发人员仍然有责任确保对线程不安全的代码区域进行同步访问。SingleThreadModel
自Servlet 2.4版本起已被弃用,并将在Servlet 6.0中删除。此更改使JSP的isThreadSafe
指令无效。 - Joakim Erdfelt首先是简短的答案 <%@page isThreadSafe="false" %>
更详细的回答是不要这样做。
你需要非常清楚你的目标。使用SingleThreadModel并没有使得Servlet真正具备线程安全性,而是设置了只有一个线程可以进入你的Servlet。我猜你这么做是因为Servlet代码不是线程安全的,如果多个线程同时访问代码会发生不好的事情。
这对我意味着你在Servlet代码中有类似这样的内容:
doGet(/*etc/*){
// ... stuff
someExistingUnsafeClass.doSomething();
// .. more stuff
}
毕竟,你的 servlet 代码本身肯定不会出现线程不安全的问题,对吧?你一定会修复它,是吗?所以肯定是一些遗留代码存在线程不安全的问题?
如果是这种情况,在你的 JSP 中需要使用现有的遗留代码,在其中某个地方会调用不安全的内容:
<%
someExistingUnsafeClass.doSomething();
%>
因此,您只需要保护这个不安全的调用:
<%
synchronized(this){
someExistingUnsafeClass.doSomething();
};
%>
允许大部分JSP以正确的线程运行将会提高性能。
我还应该说,如果您将应用程序构建为MVC,则所有不安全的代码都是从控制器调用的,视图(即JSP)永远不需要不安全。
如果您的JSP页面没有任何状态信息(即没有实例变量可以在不同请求之间更改),那么它们是线程安全的。
service()
中的局部变量。不需要。
JSP基本上是一个servlet中的单个方法。正如您可能已经知道的那样,方法是线程安全的,也就是说,同时调用同一对象的同一方法的两个线程将在各自的堆栈中执行。
因此,您实际上不需要创建一个线程安全的JSP,因为它已经是线程安全的。
如果您在JSP中声明变量a
,则没有其他请求可以看到该变量。
您必须注意的是,放入会话或上下文中的对象可能会被多个线程同时访问,或者几乎不是线程安全的代码。然后,您必须同步或注意这些对象!而不是JSP页面本身。