我有一个global variable
被调用loginAttempt
的servlet class
. global variable
如果两个人requests
同时命中会发生什么?会发生什么是无法预料的事件。
在 servlet 中有全局变量是邪恶的吗?
如果我每次都把它放在loginAttempt
一边初始化。doPost()
我有一个global variable
被调用loginAttempt
的servlet class
. global variable
如果两个人requests
同时命中会发生什么?会发生什么是无法预料的事件。
在 servlet 中有全局变量是邪恶的吗?
如果我每次都把它放在loginAttempt
一边初始化。doPost()
是的。
您的变量可由任何其他类读取/写入。您无法控制以确保他们都用它做明智的事情。其中一个可能会覆盖它/错误地增加它,等等
这是每个 JVM 的一个 servlet 实例。因此,线程可能会尝试同时访问它。因为它是全局的,并且您没有提供任何同步/访问控制,所以它不是线程安全的。此外,如果您曾经在具有不同 JVM 的某种集群中运行 servlet,那么该变量将不会在它们之间共享,并且您将拥有多个 loginAttempt 变量。
如果您必须将它放在 servlet 中,请将其设为静态但不要公开。提供 getter/setter 来访问和更新它。了解线程安全编程,以便多线程可以对其进行更新和安全读取。
更好的是,将其存储在 servlet-context 中。这应该是您像这样存储 servlet 范围的数据的地方。
只要您了解通常只创建一个 servlet 的单个实例并且全局变量将由该 servlet 的所有客户端共享 - 即每个请求,同时在不同线程上和多个同时用户。
我猜你的全局变量loginAttempt
正在计算登录尝试的次数,那么只要这是以线程安全的方式完成的,那么计算在这个 servlet 上进行的登录尝试次数是一种合理的方法。不过,这将适用于所有用户。如果您希望每个用户都尝试登录,那么您可能需要创建一个会话并使用会话上下文来存储此类信息。
在大量并发访问时,可能要注意Servlet的线程安全问题……可以尝试以下方法来避免这个问题……
1、</p>
public class loginAttempt extends HttpServlet implements SingleThreadModel {
...
}
二、方法二:使用synchronized
关键字
三、避免使用全局变量
将其存储为会话属性。否则全局变量的概念会彻底搞砸你。使用会话是一个好主意,因为它是 1) 如果重新启动 Web 服务,会话数据不会丢失
2) 在负载均衡的环境中,会话数据存储在一个中央位置,这意味着任何服务器都可以处理请求并访问会话数据。
所以它是可访问的,但它是隐藏的。
是的。
全局变量与所有人共享
这取决于,如果你的变量是只读的,它应该没问题。但在大多数情况下,全局变量是邪恶的。我无法为您提供解决方案,因为我没有您的代码,但我确信有另一种方法。
在您的用例中,它超越了邪恶。loginAttempt 将由访问 servlet 的所有线程共享
首先,global variable
Java 中没有所谓的术语。它们被称为类变量或实例变量。
其次,是的,如果您要分配请求或会话范围的数据,那么在 Servlet 中有实例变量是不好的做法,因为它将由所有线程共享。
您可以将它用于应用程序范围的值,通常从上下文参数中获得。或者如果数据永远不会像常量一样改变(不可变)。