假设我的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
?
答案 0 :(得分:2)
是的,List可以同时从多个线程读取,只要没有写入。
有关此问题的详细信息,请参阅this answer,以进一步解释此问题。有一些重要的陷阱。
答案 1 :(得分:1)
从实践中的java并发性我们得到:
安全地发布对象,包括对象的引用和 必须同时使对象的状态对其他线程可见。 正确构造的对象可以通过以下方式安全地发布:
从静态初始值设定项初始化对象引用。存储一个 将它引入一个易变的领域。存储对它的引用 最后的领域。将对它的引用存储到正确的字段中 由(同步)锁保护。
你的清单既不是这些。我建议将其设为最终版,因为这将使您的对象实际上不可变,在这种情况下就足够了。如果多次调用init(),则应该使其变为volatile。有了这个,我当然假设列表元素没有发生任何变化,也没有公开列表中的任何元素(如String eventTextNoHTML = eventText.substring(beginIndex, endIndex);
方法等。