【问题标题】:How much to worry about threading in Java EE applications?Java EE 应用程序中的线程有多担心?
【发布时间】:2015-04-14 23:27:45
【问题描述】:

我有一个带有一些 servlet、JSP(它们也是 servlet,对吗?)、SOAP Web 服务(又是 servlet?)和 REST Web 服务(也许是……servlet?)的 Java EE Web 应用程序。

我的问题是:我有多少需要担心多线程?我自己并没有明确地创建线程,而是让容器担心这一点。

例如,如果我为某些类有一个 JAXB 上下文的缓存(静态映射)以加快编组和解组的速度,我是否必须同步对它的访问?

我还维护了一个反复使用的基本 XSLT 模板的缓存(又是静态映射),同样的问题吗?

【问题讨论】:

  • 你不必担心创建线程——服务器会为你做这件事——但你必须意识到你写的所有东西都可能被许多人访问并发线程。
  • @DaveHowes OP 并不担心创建线程。 OP关心的是同步共享资源(缓存,由Map实现)。
  • 这里有很多问题!我可能会建议您使用 ehcache,它只是一张地图,但他们已经为您完成了所有这些令人担忧的事情。
  • @Richard ehcache 不仅仅是Map...
  • 当然。但就所有意图和目的而言……它只是一张地图。

标签: java multithreading jakarta-ee servlets


【解决方案1】:

如果您不需要像 EHCache 这样的整个库/框架的重量级功能,您可以使用现有/提供的 JavaEE API 轻松确保线程安全。只需创建一个 @Singleton EJB(请参阅下面的示例链接),它使用容器管理的并发来管理您的 Map 的访问,并将此 EJB 注入(使用 @EJB)到您的 Servlet 或 JAX- RS 资源。如果您需要注入到 JSP 中,您可以编写一个小的实用程序方法来查找 EJB,因为注入注释在 JSP 中不起作用。

1 - Singleton Session Bean Example

【讨论】:

    【解决方案2】:

    我只是想在这里添加一个答案。 正如您所暗示的,在 java 中,如果它使用 HTTP,那么当您开始使用它时,很有可能它是某种 servlet。

    只要您遵守规则,您就不必担心多线程在负载或死锁等方面的问题。 正如其他人指出的那样,Servlet 在请求之间共享。如果您将任何包含“状态”(servlet 中的成员变量)的内容放入其中,它将被共享,因此可以同时访问。 您的地图绝对是其中之一。

    我建议您研究一下 EHCache,它是一种“内存中”缓存解决方案,非常适合您的目的。在使用时,它看起来就像一张地图。

    Element element = new Element("key1", "value1");
    cache.put(element);
    

    但它会管理您放入其中的对象的整个生命周期,何时过期等。它还为您处理并发。这就是我通常所说的“自动魔法”。

    EHCache 的最大优点是您还可以使用它来扩展您的应用程序。您可以运行相同的服务器,使用循环负载平衡器 (apache) 来选择哪个服务器获取下一个请求,并在实例之间共享缓存。 EHCache 正在被其他缓存机制所取代,但在我看来,它仍然是迄今为止最好的解决方案。它非常适合您的目的。 (我不为兵马俑工作!)

    【讨论】:

      【解决方案3】:

      如果您的 servlet 或类似程序仅对您的共享资源使用读取操作,例如Map#get(someKey) 那就不用担心了。

      如果 servlet 或类似程序中有一个进程可以改变共享资源的状态,例如Map#put(someKey, someValue) 而其他资源可能正在使用读取操作,那么是的,您应该使用同步或使用 ConcurrentHashMap

      除此之外,请确保存储在缓存中的对象的状态不能被客户端更改,以避免应用程序中出现其他问题。请注意,这些问题(可能)不会引发ConcurrentModificationException,但您会注意到影响。

      【讨论】:

      • Read 还需要担心多线程,例如如果他创建了一个有状态的 servlet,它将开始跨会话共享重要信息。
      • 我没有投反对票,但我觉得你写的不太对劲。当然,他需要考虑他放置在地图中的对象也必须是线程安全的。如果两个线程从 map 中读取同一个对象并都使用它,并且该对象不是线程安全的,那么就不能保证行为可以吗?
      • @kamoor 定义有状态的 servlet 是一个失败点,也是一种不好的做法。
      • @DaveHowes 无法同步。我理解您的担忧,但进入了不同的主题。
      • @LuiggiMendoza 绝对是。我只举一个例子,为什么他需要担心阅读。跨会话共享的任何对象都需要重新访问,并确保它可以共享或同步。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-02
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      • 2012-05-29
      相关资源
      最近更新 更多