【问题标题】:Java EE Servlet - Should I synchronize each access to application scope? [duplicate]Java EE Servlet - 我应该同步对应用程序范围的每次访问吗? [复制]
【发布时间】:2015-07-25 23:06:09
【问题描述】:

我看到一个很有趣的消息here,看起来ASP.NET的人必须同步他们对应用程序范围的访问,所以我想知道用Java EE JSP/Servlet技术开发的人是否也有同样的限制.

这里是一个例子:

public class MyServlet extends HttpServlet {
    private static Lock applicationScopeLock = new ReentrantLock();        

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response){
        applicationScopeLock.lock();
        try {
            ServletContext appScope = this.getServletContext();
            appScope.setAttribute("myKey", new MyValue());
        } finally {
            applicationScopeLock.unlock();
        }
    }
  1. 在 JSP/Servlet 技术中操作应用程序范围是否需要同步?
  2. 如果是,我应该为 setAttribute() 和 getAttribute() 使用同步(锁),还是 setAttribute() 就足够了?

谢谢。

编辑:

我看到了一个类似的主题,其中包含更多细节here²。总结Servlet Specification 3.1 (read §4.5) 只说上下文中的属性可以在同一个Web 应用程序中的不同servlet 之间共享,但没有明确说明setAttribute/getAttribute 是否是线程安全的(Javadoc 都不是)。一些 servlet 容器(如 Tomcat)使用 ConcurrentHashmap 实现(但它不是规范的一部分)。总结一下,我还读到一个好的做法是使用不可变/线程安全的对象作为值。

【问题讨论】:

  • 我认为这非常接近重复,因此没有区别。当然,链接问题中的推理适用。

标签: java jakarta-ee servlets scope synchronize


【解决方案1】:
  1. 简短的回答是是的。这是因为每个传入服务器的请求都在不同的线程中处理。由于应用程序上下文为所有请求共享,这意味着它可以以并发方式访问。

  2. 为了安全起见,我会选择两者。我什至会建议你包装整个块,处理修改一个对象,存储在应用程序上下文中,在一个同步块中。我也会尽量少用这个上下文,因为它会带来很多开销,而且如果不小心,可能会导致问题。

【讨论】:

  • 有人给了你“-1”(不是我),我不明白为什么,因为你的回答似乎合乎逻辑。
  • 只有忽略上下文才合乎逻辑。上下文是,虽然这些操作不是线程安全的 servlet 堆栈可能符合规范的字母,但大多数程序员会称它为 BROKEN。此外,您不需要做出假设。看源代码。
  • 规范中没有任何内容强制对象、被存储或线程的不变性 - 实现的安全性。由于没有具体的例子,我假设最坏的情况——有问题的对象是可变的,如果它们确实是可变的,那么它们对它们的访问应该被序列化。我也同意不可变是要走的路,但我不明白为什么我的答案被认为不正确。
猜你喜欢
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多