gpt4 book ai didi

java - 如果这不是线程安全的,我可以通过哪些方式使其成为线程安全的?

转载 作者:行者123 更新时间:2023-11-30 10:06:50 26 4
gpt4 key购买 nike

关于HTTPSession,我使用的是Java Servlets,没有框架。我已阅读有关 AtomicReferences 的内容,但不清楚如何使用它来使此代码线程安全。假设我可以简单地将 updateSessionHashSet 标记为同步以提供安全性,我是否正确?我知道不建议这样做,因为效率低下。还有哪些其他选项和语法?

HTTPServlet 内部:

private void updateSessionHashSet(HttpServletRequest req){
HashSet<String> hs = req.getSession().getAttribute("theHashSet");
String csv = req.getParameter("theCsv");

String[] arr = csv.split(",");
for(int i = 0; i < arr.length; i++){
hs.add(arr[i].trim());
}
}

public void doPost(HttpServletRequest req,HttpServletResponse res) throws IOException {
updateSessionHashSet(req);
}

最佳答案

您引用的帖子告诉您 HTTPSession 是共享状态,当多个线程可以修改它时您必须小心。这里线程干扰的机会是,如果您有两个来自同一用户的并发 POST 调用此方法。你可以通过类似的方式处理它

private void updateSessionHashSet(HttpServletRequest req){
String csv = req.getParameter("theCsv");
Set<String> hs = new HashSet<String>();
String[] arr = csv.split(",");
for(int i = 0; i < arr.length; i++){
hs.add(arr[i].trim());
}
req.getSession().setAttribute("theHashSet", hs);
}

通过这种方式,您首先将新的哈希集放在一个局部变量中,然后代码自动覆盖对 session 的 theHashSet 属性的引用。如果两个线程正在调用相同的代码,那么一个或另一个将获胜,但两个线程不会混在一起(这似乎可能发生在您发布的代码中)。

或者,您可能非常喜欢链接帖子中的一些答案建议并在 HttpSession 对象上进行同步,但是由于您正在对应用程序实例本地的 Java 对象进行同步,因此您必须注意应用程序分布在多个节点的情况。同步意味着使用共享锁,并且在 JVM 之间没有共享。

IT 部门通常希望将应用程序部署到多个实例以避免出现单点故障。您可以通过将 session 固定到特定服务器来处理同步问题,但这会使负载平衡变得困难。

顺便说一句,将内容存储在 HttpSession 中可能不是最佳计划,您应该将其保存在某种数据存储中。获得安全并发的最佳方法是最小化可变状态的数量。 HttpSession 不能用作长期存储。

关于 Java EE 线程安全的指南,我有一个相关的答案 here .

关于java - 如果这不是线程安全的,我可以通过哪些方式使其成为线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54482794/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com