java 如何创建线程安全的 JSP 页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3572712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:28:07  来源:igfitidea点击:

How can I create Thread safe JSP page

javamultithreadingjspservlets

提问by vinoth

I want to create a Thread safe JSP page. It is possible in Servlet by implementing SingleThreadModel interface but I don't know how to do it in JSP page.

我想创建一个线程安全的 JSP 页面。通过实现 SingleThreadModel 接口在 Servlet 中是可能的,但我不知道如何在 JSP 页面中做到这一点。

回答by Vineet Reynolds

Theoretically, JSP pages can be indicated as threadsafe via the isThreadSafepage directive attribute. Setting a value of false, will get the container to synchronize access to page level objects (and not to session and application scoped objects or objects of any other variety). Obviously, it is still the responsibility of the developer to ensure that synchronous access to thread unsafe regions of code.

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

Morevoer, the SingleThreadModel interface has also been deprecated in the Servlet Specification release 2.4. The SingleThreadModel interface is used to implement the supposed thread safety in JSPs as well - generated servlet classes will implement the SingleThreadModel for JSPs that use the threadsafe attribute. The specification itself outlines why the interface is deprecated:

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

SRV.2.2.1 Note About The Single Thread Model

The use of the SingleThreadModel interface guarantees that only one thread at a time will execute in a given servlet instance's service method. It is important to note that this guarantee only applies to each servlet instance, since the container may choose to pool such objects. Objects that are accessible to more than one servlet instance at a time, such as instances of HttpSession, may be available at any particular time to multiple servlets, including those that implement SingleThreadModel.

It is recommended that a developer take other means to resolve those issues instead of implementing this interface, such as avoiding the usage of an instance variable or synchronizing the block of the code accessing those resources. The SingleThreadModel Interface is deprecated in this version of the specification.

SRV.2.2.1 关于单线程模型的说明

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

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

回答by djna

First the short answer <%@page isThreadSafe="false" %>

首先是简短的回答 <%@page isThreadSafe="false" %>

The longer answer is don't do that.

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

You need to be very clear about your objective here. You haven't made a servlet truly thread-safe by using a SingleThreadModel, rather you have set things up so that only one thread at a time can get into your servlet. Presumbly you would be doing that exactly because the Servlet code is notthread safe, that is if more than one thread were to get at the code bad things would happen.

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

This implies to me that you have something like this in the servlet code:

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

   doGet(/*etc/*){

       // ... stuff

           someExistingUnsafeClass.doSomething();

       // .. more stuff

   }

After all, your serlvet code itself cannot be thread-unsafe, surely? You would fix it, right? So it must be some legacy code that's thread-unsafe?

毕竟,您的 serlvet 代码本身肯定不会是线程不安全的吗?你会修复它,对吧?那么它一定是一些线程不安全的遗留代码吗?

If this is the scenario, with your JSP needing to use that existing legacy code, somewhere in your JSP you have a call that unsafe stuff:

如果是这种情况,并且您的 JSP 需要使用现有的遗留代码,那么在您的 JSP 某处,您会调用不安全的东西:

<%
         someExistingUnsafeClass.doSomething();
%>

So you just need to protect this unsafe call:

所以你只需要保护这个不安全的调用:

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

  };
%>

Allowing the bulk of your JSP to run properly threaded will perform much better.

允许您的大部分 JSP 以正确的线程方式运行会表现得更好。

I should also say, that if you structure your application as MVC then all thread-unsafe code is called from the controller and the view (the JSP) never needs to be unsafe.

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

回答by naikus

By not having any state information in your JSP page. (No instance variables, that can change accross different requests). If you do not have any state in your JSP or servlet, they are threadsafe

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

回答by Bozho

Talking about thread-safety with JSP is wrong - JSP is a view technology and it only displays results - it doesn't do any processing. (it cando processing, but it must not)

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

Thread-safety with servlets is achieved by having noprivate fields in the servlet - the servlet instance is one for the whole container and each request is a new thread invoking the service(..)method.

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

You should specify exactly what you mean by "thread-safety" in your case - i.e. what do you expect to fail.

在您的情况下,您应该准确指定“线程安全”的含义 - 即您希望失败的内容。

回答by Truong Ha

In JSP, just use variables in scriplets and you can be confident that they are thread safe because they will be translated into local variable in service().

在 JSP 中,只需在脚本中使用变量,您就可以确信它们是线程安全的,因为它们将在service().

回答by OscarRyz

You don't.

你没有。

JSP is basically a single method in a servlet. As you may know already, methods are thread safe, the the sense, that two threads invoking the same method of the same object at the same time, will execute each one in its own stack.

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

So, you don't really need to make a thread safe JSP, because, it is trade safe already.

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

If you declare a variable ain a JSP, there is no way, another request sees that variable.

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

What you must be aware of, is, objects put into the session, or the context may be accessed by multiple threads at the same time, or pretty much not thread safe code. Then what you must synchronize or take care of, are those objects!, and not the JSP page it self.

您必须注意的是,将对象放入会话中,或者上下文可能被多个线程同时访问,或者几乎不是线程安全的代码。那么你必须同步或处理的是那些对象!,而不是 JSP 页面本身。