Java:使用静态变量在基于web的应用程序中存储特定于应用程序的数据
我正在开发一个现有的基于web的应用程序,它使用静态映射来存储特定于该应用程序的数据 下面是我的代码,负责在Java:使用静态变量在基于web的应用程序中存储特定于应用程序的数据,java,Java,我正在开发一个现有的基于web的应用程序,它使用静态映射来存储特定于该应用程序的数据 下面是我的代码,负责在ConcurrentHashMap中存储数据,如下所示 public class MyClass // Class variable private static Map<String, UserThread> usermap = new ConcurrentHashMap<String, UserThread>(); // Inside
ConcurrentHashMap
中存储数据,如下所示
public class MyClass
// Class variable
private static Map<String, UserThread> usermap = new ConcurrentHashMap<String, UserThread>();
// Inside a Method
public void userData()
{
UserThread userThread= usermap.get(getLoginId());
if (userThread == null) {
userThread = new UserThread();
userThread.start();
usermap.put(getLoginId(), userThread);
}
}
公共类MyClass
//类变量
私有静态映射usermap=new ConcurrentHashMap();
//方法内部
公共void userData()
{
UserThread UserThread=usermap.get(getLoginId());
if(userThread==null){
userThread=newuserthread();
userThread.start();
put(getLoginId(),userThread);
}
}
应用程序运行良好,我的问题是,这是一个有效的代码,因为我们可以在静态变量中存储数据吗??(此处静态
ConcurrentHashMap
包含特定于应用程序的数据)在这种情况下,将在一台机器上登录的用户将拥有与在第二台机器上相同的会话。我打赌这不是一个好办法
不久前我曾询问过,Alessandro Santini使用
ThreadLocal
为我提供了非常好的解决方案。检查此项。在这种情况下,将在一台计算机上登录的用户将与在第二台计算机上登录的用户拥有相同的会话。我打赌这不是一个好办法
不久前我曾询问过,Alessandro Santini使用
ThreadLocal
为我提供了非常好的解决方案。检查此项。使用静态映射,除非您确定添加到映射中的每个条目的生命周期,即谁将添加它们、条目将在那里停留多长时间以及何时删除它们以便在GC期间声明,否则您将面临内存泄漏的风险。否则,您的应用程序将耗尽内存并开始抛出OOME。使用静态映射,您将面临内存泄漏的风险,除非您确定添加到映射的每个条目的生命周期,即谁将添加它们,条目将在那里停留多长时间,何时将它们删除,以便在GC期间声明它们。否则,应用程序将耗尽内存并开始抛出OOME。应避免任何类型的静态变量和缓存,尤其是在多线程环境(如web应用程序)中。您的代码有几个问题:
if(UserThread==null)
和usermap.put(getLoginId(),UserThread)之间添加一个UserThread代码>。HashMap的Concurent版本并不像看上去那样神奇地解决了线程安全的所有问题李>
在servlet容器中生成自己的线程不是一个好主意。有更好的方法来完成后台任务,但首先需要说明线程正在尝试做什么
在任何类型的应用程序中,通常使用任何类型的静态缓存都是一个坏主意。在您的情况下,最好在用户会话中保留特定于应用程序的数据。应避免任何类型的静态变量和缓存,尤其是在多线程环境中,如web应用程序。您的代码有几个问题:
是否从映射中删除用户线程?你怎么知道什么时候应该移除它们?如果客户端的浏览器崩溃怎么办?如果不删除它们,则在应用程序运行一段时间后,您会要求出现内存不足错误李>
以使用ConcurrentHashMap的方式使用它不是线程安全的,因为另一个线程可能会在if(UserThread==null)
和usermap.put(getLoginId(),UserThread)之间添加一个UserThread代码>。HashMap的Concurent版本并不像看上去那样神奇地解决了线程安全的所有问题李>
在servlet容器中生成自己的线程不是一个好主意。有更好的方法来完成后台任务,但首先需要说明线程正在尝试做什么
在任何类型的应用程序中,通常使用任何类型的静态缓存都是一个坏主意。在您的情况下,最好将特定于应用程序的数据保留在用户会话中
根据规范,在容器中启动自己的线程是不合适的。您应该为此使用WorkManager。但据我所知,唯一一个真正执行该规则的服务器是WebSphereApplicationServer
静态变量原则上是可以的,当然,如果您在集群环境中运行,那么每个服务器都将有自己的静态变量实例。这可能是个问题,也可能不是
所以从技术上说你可能会没事
另一方面,我真的很好奇,你想用这些线程实现什么。如果你启动一个线程,每个用户都是一个优秀的攻击向量DoS攻击。我也不知道你为什么要这样做
根据规范,在容器中启动自己的线程是不合适的。您应该为此使用WorkManager。但据我所知,唯一一个真正执行该规则的服务器是WebSphereApplicationServer
静态变量原则上是可以的,当然,如果您在集群环境中运行,那么每个服务器都将有自己的静态变量实例。这可能是个问题,也可能不是
所以从技术上说你可能会没事
另一方面,我真的很好奇,你想用这些线程实现什么。如果你启动一个线程,每个用户都是一个优秀的攻击向量DoS攻击。我也不知道你为什么要这样做。我不是说这是最好的主意,而是