当多个线程访问/修改上下文变量但在会话级别无法产生相同的行为时,我已经尝试了不一致性。例如,当同一个sessionid的两个请求(这意味着两个线程)进入时,服务方法中调用session.setAttribute(“something”)方法不会导致竞争条件。是不是因为Tomcat为会话变量提供了线程安全性,或者我有完全错了?
答案 0 :(得分:6)
Servlet规范3.0明确规定对会话密钥的访问是线程安全的,见7.7.1节。 但是,访问存储在这些键下的元素不是线程安全的。在这种情况下,必须由应用程序开发人员确保线程安全。
7.7.1线程问题 执行请求线程的多个servlet可以具有对它的活动访问权 会话对象同时出现。容器必须确保操纵 表示会话属性的内部数据结构在线程中执行 安全的方式。开发人员负责线程安全访问 属性对象本身。这将保护内部的属性集合 来自并发访问的HttpSession对象,消除了一个机会 应用程序导致该集合损坏。
示例代码说明了这一点:
HttpSession session;
List items;
session.put("cart", items); // thread1 writes cart reference to session, this is thread-safe
...
items = session.get("cart"); // thread1 reads cart reference from session, this is thread-safe
items.get(0); // access to elements of application collection is *not* thread-safe, you must use explicit synchronization here.
我相信“线程安全方式”的含义是HttpSession
访问方法保证是线程安全的,但是通过这些元素的方法对会话中存储的元素的所有访问不保证是线程安全的。
答案 1 :(得分:1)
稍微阅读一下(其中this bug fix),我确实得到了强烈的印象,即会话是线程安全的,或者应该是。
答案 2 :(得分:1)
你知道所有上下文变量都是线程不安全的,除了本地,所以如果你试图访问/修改这个上下文变量使用锁,在java中它是synchronized
个对象,有关更多信息,请阅读 Head First Servlets& JSP - 第5章。祝你好运!