2012-08-24 29 views
2

我目前必须使线程安全的特定Java servlet实现。代码不是由我写的,我没有涉及它的设计或任何其他东西。我“只是”必须使它线程安全的:)有关Java Servlets的详细线程安全问题

我不是线程安全初学者,但不是专业无论是。 Servlets(或多或少)对我来说是全新的。我已经完成了一些教程并了解了有关servlet的基础知识,但就是这样。我可以找到有关使servlet线程安全的所有教程都很肤浅,我仍然有一些未解答的问题,我似乎无法找到答案。一些帮助将不胜感激。

1.)据我所知,HttpServletRequests和HttpServletResponses不是在不同的线程之间共享的,所以我不需要在它们上同步读写访问(这是否正确?)。但是HttpServletRequestWrappers等呢?

2.)我必须同步访问由getServletContext()返回的ServletContext对象,特别是如果我使用setAttribute()对吧?

3.)HttpServletRequests有一个getCookies()方法。这些Cookie可能在不同请求之间共享,或者每个请求是否拥有自己的Cookie对象(即使它们代表相同的“真实”cookie)?以不同的方式提问:我是否必须同步对返回的cookie对象的访问?

感谢您花时间阅读我的问题。我期待着你的答案:)

回答

1

的Servlet不是线程安全的,因为应用服务器可以保持servlet或实例池的单个实例并在多个传入的请求共享。因此,servlet不应该有任何状态(即servlet对象级变量不是线程安全的)。 Servlet规范以前有SingleThreadModel接口来强制给定的servlet是线程安全的,但从2.3开始已经弃用了,我想。

对策:

  1. 权,这些都是paramters到HTTP方法等的doGet和doPost并因此访问这些不需要同步。

  2. 正确的,因为getServletContext()方法返回一个上下文级的对象是所有的servlet和运行这个servlet的所有线程访问。

  3. 每个请求都附带自己的一组cookie。同样,这是从方法参数HttpServletRequest获得的,因此访问不需要同步。

1

当你让servlets线程安全时,你很少需要同步。 Servlets也应该从头开始是线程安全的,因为单个servlet实例可能会被多个用户使用。另外,你不能相信只有一个servlet实例,除非你的servlet容器指定总是只有一个实例。

1)与请求和响应对象处理,因为只有一个线程可以同时处理的请求时,不需要进行同步。

2)你应该尝试在你没有在ServletContext中设置一个servlet内的任何值的方式来设计应用程序。通常,ServletContext在启动时被初始化,然后被servlet或过滤器用作只读。我不确定它是否应该是线程安全的,但是如果您在同一请求中设置了多个值,则必须同步,以便读取这些值的servlet不会混乱。但这是基本的线程安全问题,并不特别与servlet有关。

3)不需要同步cookie,因为它们处理当前的请求,只有一个线程可以做到这一点。

新的servlet容器允许异步模型,其中多个线程可以处理单个请求,但它仍然是一次一个线程。

1
  1. 你的理解是正确的。实际上,线程是为每个请求创建的。所以HttpServletRequestHttpServletResponse是本地线程。所以不要分享这两个。你不需要同步它们。 HttpServletRequestWrapperHttpServletResponseWrapper是分别提供了一个方便的实现接口的类。您不需要在同步上下文中担心它们。

  2. 当然,您必须为ServletContext object returned by getServletContext()提供同步,因为它在应用程序中的servlet之间共享。

  3. 由于HttpServletRequest是由容器创建的线程的局部,以便为请求提供服务。所以cookie也是该线程的本地,并且这些不共享。所以不需要提供与cookies的同步。

几个概念:

  1. 应用程序中Servlet总是singlton。即仅创建一个对象。
  2. 对于每个请求,创建一个不同的线程(实际上从线程池获得)。以下是本地线程:HttpServletRequest,HttpServletResponse