-3

我有一个global variable被调用loginAttemptservlet class. global variable如果两个人requests同时命中会发生什么?会发生什么是无法预料的事件。

在 servlet 中有全局变量是邪恶的吗?

如果我每次都把它放在loginAttempt一边初始化。doPost()

4

8 回答 8

4

是的。

  1. 您的变量可由任何其他类读取/写入。您无法控制以确保他们都用它做明智的事情。其中一个可能会覆盖它/错误地增加它,等等

  2. 这是每个 JVM 的一个 servlet 实例。因此,线程可能会尝试同时访问它。因为它是全局的,并且您没有提供任何同步/访问控制,所以它不是线程安全的。此外,如果您曾经在具有不同 JVM 的某种集群中运行 servlet,那么该变量将不会在它们之间共享,并且您将拥有多个 loginAttempt 变量。

如果您必须将它放在 servlet 中,请将其设为静态但不要公开。提供 getter/setter 来访问和更新它。了解线程安全编程,以便多线程可以对其进行更新和安全读取。

更好的是,将其存储在 servlet-context 中。这应该是您像这样存储 servlet 范围的数据的地方。

于 2013-06-06T08:04:46.387 回答
2

只要您了解通常只创建一个 servlet 的单个实例并且全局变量将由该 servlet 的所有客户端共享 - 即每个请求,同时在不同线程上和多个同时用户。

我猜你的全局变量loginAttempt正在计算登录尝试的次数,那么只要这是以线程安全的方式完成的,那么计算在这个 servlet 上进行的登录尝试次数是一种合理的方法。不过,这将适用于所有用户。如果您希望每个用户都尝试登录,那么您可能需要创建一个会话并使用会话上下文来存储此类信息。

于 2013-06-06T08:05:04.293 回答
1

在大量并发访问时,可能要注意Servlet的线程安全问题……可以尝试以下方法来避免这个问题……

1、</p>

public class loginAttempt extends HttpServlet implements SingleThreadModel {
...
}

二、方法二:使用synchronized关键字

三、避免使用全局变量

于 2013-06-06T08:14:52.157 回答
1

将其存储为会话属性。否则全局变量的概念会彻底搞砸你。使用会话是一个好主意,因为它是 1) 如果重新启动 Web 服务,会话数据不会丢失

2) 在负载均衡的环境中,会话数据存储在一个中央位置,这意味着任何服务器都可以处理请求并访问会话数据。

所以它是可访问的,但它是隐藏的。

于 2013-06-06T08:15:27.000 回答
0

是的。
全局变量与所有人共享

于 2013-06-06T07:57:59.913 回答
0

这取决于,如果你的变量是只读的,它应该没问题。但在大多数情况下,全局变量是邪恶的。我无法为您提供解决方案,因为我没有您的代码,但我确信有另一种方法。

于 2013-06-06T07:58:05.317 回答
0

在您的用例中,它超越了邪恶。loginAttempt 将由访问 servlet 的所有线程共享

于 2013-06-06T07:59:56.023 回答
0

首先,global variableJava 中没有所谓的术语。它们被称为类变量或实例变量。

其次,是的,如果您要分配请求或会话范围的数据,那么在 Servlet 中有实例变量是不好的做法,因为它将由所有线程共享。

您可以将它用于应用程序范围的值,通常从上下文参数中获得。或者如果数据永远不会像常量一样改变(不可变)。

于 2013-06-06T08:43:38.527 回答