在servlet中共享线程访问数组。使用哪种实现方式?

时间:2016-01-31 22:10:57

标签: java servlets concurrency

假设我的servlet中有这样的代码:

private static final String RESOURCE_URL_PATTERN = "resourceUrlPattern";
private static final String PARAM_SEPARATOR = "|";

private List<String> resourcePatterns;

@Override
public void init() throws ServletException {
    String resourcePatterns = getInitParameter(RESOURCE_URL_PATTERN);
    this.resourcePatterns = com.google.common.base.Splitter.on(PARAM_SEPARATOR).trimResults().splitToList(resourcePatterns);
}

如果永远不会修改此线程,'resourcePatterns'是否安全?

让我们这样说:

private boolean isValidRequest(String servletPath) {
    for (String resourcePattern : resourcePatterns) {
        if (servletPath.matches(resourcePattern)) {
            return true;
        }
    }
    return false;
}

在这种情况下我应该使用CopyOnWriteArrayList还是ArrayList

2 个答案:

答案 0 :(得分:2)

是的,List可以同时从多个线程读取,只要没有写入。

有关此问题的详细信息,请参阅this answer,以进一步解释此问题。有一些重要的陷阱。

答案 1 :(得分:1)

从实践中的java并发性我们得到:

  

安全地发布对象,包括对象的引用和   必须同时使对象的状态对其他线程可见。   正确构造的对象可以通过以下方式安全地发布:

     

从静态初始值设定项初始化对象引用。存储一个   将它引入一个易变的领域。存储对它的引用   最后的领域。将对它的引用存储到正确的字段中   由(同步)锁保护。

你的清单既不是这些。我建议将其设为最终版,因为这将使您的对象实际上不可变,在这种情况下就足够了。如果多次调用init(),则应该使其变为volatile。有了这个,我当然假设列表元素没有发生任何变化,也没有公开列表中的任何元素(如String eventTextNoHTML = eventText.substring(beginIndex, endIndex);方法等。