我目前必须使特定的Java servlet实现成为线程安全的。 代码不是由我编写的,我没有涉及它的设计或任何东西。我“只是”必须使其成为线程安全的:)
我不是线程安全的初学者,但也不是专业人士。 Servlet(或多或少)对我来说是全新的。我已经完成了一些教程并了解了有关servlet的基础知识,但就是这样。我能找到关于使servlet线程安全的所有教程都是肤浅的,我仍然有一些未解决的问题,我似乎无法找到答案。一些帮助将非常感激。
1。)根据我的理解,HttpServletRequests和HttpServletResponses不在不同的线程之间共享,所以我不需要同步它们的读写访问(这是正确的吗?)。但是HttpServletRequestWrappers等呢?
2.。)我必须同步访问getServletContext()返回的ServletContext对象,特别是如果我对它使用setAttribute(),对吗?
3.)HttpServletRequests有一个getCookies()方法。这些Cookie是否可能在不同请求之间共享,或者每个请求是否都有自己的Cookie对象(即使它们代表相同的“真实”cookie)?问的不同:我是否必须同步对返回的cookie对象的访问?
感谢您花时间阅读我的问题。我期待着你的回答:)
答案 0 :(得分:1)
Servlet不是线程安全的,因为应用程序服务器可以维护servlet的单个实例或实例池,并在多个传入请求之间共享它们。因此,servlet不应该具有任何状态(即servlet对象级变量不是线程安全的)。 Servlet规范过去曾用SingleThreadModel
接口来强制给定的servlet是线程安全的,但是我认为它已经被弃用了。
对策:
是的,这些是像doGet和doPost这样的HTTP方法的参数,因此无需同步对这些方法的访问。
正确,因为getServletContext()返回一个上下文级别对象,所有servlet和运行给定servlet的所有线程都可以访问该对象。
每个请求都附带自己的一组Cookie。同样,这是从方法参数HttpServletRequest获得的,因此访问不需要同步。
答案 1 :(得分:1)
当您使servlet线程安全时,您很少需要同步。 Servlet也应该从一开始就是线程安全的,因为多个用户可能会使用单个servlet实例。另外,你不能相信只有一个servlet实例,除非你的servlet容器指定总是只有一个。
1)处理请求和响应对象时不需要同步,因为一次只有一个线程可以处理请求。
2)您应该尝试以不必在Servlet内的ServletContext中设置任何值的方式设计应用程序。通常ServletContext在启动时初始化,然后由servlet或过滤器用作只读。我不确定它是否应该是线程安全的,但如果你在同一个请求中设置多个值,你必须同步,这样读取这些值的servlet就不会搞砸了。但这是基本的线程安全问题,并不特别与servlet有关。
3)无需同步cookie,因为它们处理当前请求,只有一个线程可以执行。
新的servlet容器允许异步模型,其中多个线程可以处理单个请求,但它一次仍然是一个线程。
答案 2 :(得分:1)
您的理解是正确的。实际上,为每个请求创建了线程。因此HttpServletRequest
和HttpServletResponse
是线程的本地。所以没有分享这两个。您不需要同步它们。 HttpServletRequestWrapper
和HttpServletResponseWrapper
是分别提供HttpServletRequest
和HttpServletResponse
接口的便捷实现的类。您无需在同步上下文中担心它们。
当然,您必须为ServletContext object returned by getServletContext()
提供同步,因为它在应用程序中的servlet之间共享。
由于HttpServletRequest
是由容器创建的线程的本地服务器来提供请求。因此,cookie也是该线程的本地,并且不会共享。因此无需为cookie提供同步。
几乎没有概念:
HttpServletRequest
,HttpServletResponse