我有一个 global variable 打电话 loginAttempt 在一个 servlet class . 这个会怎么样 global variable 如果两个 requests 在同一时间发生?将会发生的是一个不可预见的事件。在servlet中使用全局变量是一种罪恶吗??如果我把 loginAttempt 是侧面 doPost() 每次都是初始化。
global variable
loginAttempt
servlet class
requests
doPost()
gdx19jrr1#
对。您的变量可由任何其他类读取/写入。你无法控制,以确保他们都用它做明智的事情。其中一个可能会覆盖它/错误地增加它,等等每个jvm都有一个servlet示例。因此,线程可能会尝试同时访问它。因为它是全局的,并且您没有提供任何同步/访问控制,所以它将不是线程安全的。另外,如果您曾经使用不同的jvm在某种集群中运行servlet,那么变量将不会在它们之间共享,并且您将拥有多个loginattest变量。如果必须将它放在servlet中,请将其设置为静态,但不要将其公开。提供getter/setter来访问和更新它。了解线程安全编程,以便多个线程可以安全地更新和读取它。更好的是,将其存储在servlet上下文中。应该在这里存储像这样的servlet范围的数据。
z2acfund2#
在大量并发访问中,您可能需要注意servlet的线程安全问题…您可以尝试以下方法来避免这个问题。。。1、
public class loginAttempt extends HttpServlet implements SingleThreadModel { ... }
2、 第二种方法:使用 synchronized 关键字3、 避免使用全局变量
synchronized
rkttyhzu3#
在你的情况下,它是超越邪恶的。所有访问servlet的线程都将共享LoginAttent
ma8fv8wu4#
首先,没有所谓的术语 global variable 在 java 。它们被称为类变量或示例变量。第二,如果要分配请求或会话范围内的数据,那么在servlet中使用示例变量是不好的做法,因为它将由所有线程共享。您可以将它用于应用程序范围的值,这些值通常是从上下文参数获得的。或者如果数据从未像常量一样改变(不变)。
a14dhokn5#
将其存储为会话属性。否则全局变量的概念会把你搞砸。使用会话是一个好主意,因为1)如果重新启动web服务,会话数据不会丢失2) 在负载平衡的环境中,会话数据存储在中心位置,这意味着任何服务器都可以为请求提供服务并访问会话数据。所以它是可以接近的,但它是隐藏的。
k4emjkb16#
这取决于,如果您的变量是只读的,它应该是好的。但在大多数情况下,全局变量是邪恶的。我不能给你一个解决方案,因为我没有你的代码,但我相信有一个替代方法。
bmvo0sr57#
对。全局变量与所有人共享
vawmfj5a8#
只要您了解通常只创建一个servlet示例,并且该servlet的所有客户机都将共享全局变量,即每个请求,在同一时间在不同线程上,并由多个用户共享,那么它们就不是邪恶的。我猜你的全局变量 loginAttempt 在计算登录尝试次数时,只要是以线程安全的方式进行的,那么计算在这个servlet上进行的登录尝试次数将是一种合理的方法。不过,这对所有用户都适用。如果希望每个用户都有登录尝试,那么可能需要创建一个会话,并使用会话上下文来存储此类信息。
8条答案
按热度按时间gdx19jrr1#
对。
您的变量可由任何其他类读取/写入。你无法控制,以确保他们都用它做明智的事情。其中一个可能会覆盖它/错误地增加它,等等
每个jvm都有一个servlet示例。因此,线程可能会尝试同时访问它。因为它是全局的,并且您没有提供任何同步/访问控制,所以它将不是线程安全的。另外,如果您曾经使用不同的jvm在某种集群中运行servlet,那么变量将不会在它们之间共享,并且您将拥有多个loginattest变量。
如果必须将它放在servlet中,请将其设置为静态,但不要将其公开。提供getter/setter来访问和更新它。了解线程安全编程,以便多个线程可以安全地更新和读取它。
更好的是,将其存储在servlet上下文中。应该在这里存储像这样的servlet范围的数据。
z2acfund2#
在大量并发访问中,您可能需要注意servlet的线程安全问题…您可以尝试以下方法来避免这个问题。。。
1、
2、 第二种方法:使用
synchronized
关键字3、 避免使用全局变量
rkttyhzu3#
在你的情况下,它是超越邪恶的。所有访问servlet的线程都将共享LoginAttent
ma8fv8wu4#
首先,没有所谓的术语
global variable
在 java 。它们被称为类变量或示例变量。第二,如果要分配请求或会话范围内的数据,那么在servlet中使用示例变量是不好的做法,因为它将由所有线程共享。
您可以将它用于应用程序范围的值,这些值通常是从上下文参数获得的。或者如果数据从未像常量一样改变(不变)。
a14dhokn5#
将其存储为会话属性。否则全局变量的概念会把你搞砸。使用会话是一个好主意,因为1)如果重新启动web服务,会话数据不会丢失
2) 在负载平衡的环境中,会话数据存储在中心位置,这意味着任何服务器都可以为请求提供服务并访问会话数据。
所以它是可以接近的,但它是隐藏的。
k4emjkb16#
这取决于,如果您的变量是只读的,它应该是好的。但在大多数情况下,全局变量是邪恶的。我不能给你一个解决方案,因为我没有你的代码,但我相信有一个替代方法。
bmvo0sr57#
对。
全局变量与所有人共享
vawmfj5a8#
只要您了解通常只创建一个servlet示例,并且该servlet的所有客户机都将共享全局变量,即每个请求,在同一时间在不同线程上,并由多个用户共享,那么它们就不是邪恶的。
我猜你的全局变量
loginAttempt
在计算登录尝试次数时,只要是以线程安全的方式进行的,那么计算在这个servlet上进行的登录尝试次数将是一种合理的方法。不过,这对所有用户都适用。如果希望每个用户都有登录尝试,那么可能需要创建一个会话,并使用会话上下文来存储此类信息。