我正在尝试使用会话使servlet成为线程安全的。我已经阅读了不同的技术,例如synchronized块,AtomicReference或ConcurrentHashMap。如果有的话,每种技术的权衡取舍是什么?
答案 0 :(得分:4)
servlet的第一个目标是通过无共享状态来实现线程安全。将servlet部署到负载平衡群集时,任何共享状态都将失败。因此,如果您的共享状态不是缓存的味道,这意味着它总是可以从耐用的商店重建,那么您不应该首先使用它。
但是,除了这些问题之外,如果没有提供有关您尝试使用共享状态解决的问题的任何详细信息,则无法获得一个通用的答案。你提到的所有技术都有其优点,这就是为什么他们在使用Java 15年后仍然和我们在一起。
答案 1 :(得分:1)
servlet不应该具有状态,即无论如何都受其请求处理方法影响的实例或静态变量(另外它的请求处理方法不应该影响任何共享对象的状态)。每个servlet容器只有一个servlet实例,每个请求都使用一个运行相应Servlet方法的新线程处理(更常见的是doGet()或doPost())。
但是,servlet API提供了以开箱即用的线程安全方式存储与特定用户会话相关的数据所需的所有功能。例如,您可以通过HttpServletRequest#getSession()获取会话,并使用其setAttribute()方法在特定会话中存储对象,并使用getAttribute()将它们返回到同一会话的另一个请求。
希望这有帮助。
答案 2 :(得分:0)
首先,servlet应该是无状态的,这有利于应用程序的可伸缩性。实际上,基于Servlet API的会话对象是高度可扩展的,您可以编写自己的HttpSession实现来使Session访问线程安全。 恕我直言,你应该提供你的场景的更多细节,因为在你上面提到的那些数据结构中,最后两个似乎与Session的线程安全访问无关。