gpt4 book ai didi

java - 什么情况下就不是线程安全的

转载 作者:太空宇宙 更新时间:2023-11-04 07:38:54 25 4
gpt4 key购买 nike

所有,为了更好地理解HttpSession线程问题的Attributes。我为其编写了一些测试代码,我认为下面的代码应该是线程安全的方式。

HttpSession session = request.getSession();
synchronized (session) {
Integer n = (Integer) session.getAttribute("foo");
session.setAttribute("foo", (n == null) ? 1 : n + 1);
}

但实际上Answer它告诉我它不是。我只是无法理解,在我看来,我认为 session 是一个客户端和服务器之间的转换。这种情况是否有任何线程问题?如果有,请告诉我在哪种情况下这段代码不是线程安全的。谢谢。

最佳答案

据我所知,每次线程请求 session (即真实 session 上的代理)时,没有什么可以阻止 servlet 容器返回不同的对象。

如果容器这样做,在 session 上同步将不会有任何帮助,因为每个线程将在不同的对象上同步。

拥有线程安全计数器的最简单方法是使用 AtomicInteger,并调用其增量方法之一,但这并不能阻止两个并发线程第一次存储 AtomicInteger(如果它们都将其视为 null)。

最简单的确定方法(尽管可能不是最快)是使用全局锁来获取属性:

public static synchronized AtomicInteger getCounterFromSession(HttpSession session) {
AtomicInteger counter = (AtomicInteger) session.getAttribute("counter");
if (counter == null) {
counter = new AtomicInteger();
session.setAttribute("counter", counter);
}
return counter;
}
也就是说,在集群应用程序中, session 会在集群的节点之间持久化或复制,因此这也不会带来任何保证。将计数器存储在数据库中将是这里的解决方案。

关于java - 什么情况下就不是线程安全的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16373903/

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