编程语言
首页 > 编程语言> > java-Apache HttpClient中未修改的ArrayList中的ConcurrentModificationException

java-Apache HttpClient中未修改的ArrayList中的ConcurrentModificationException

作者:互联网

如果在生产中抛出ConcurrentModificationException,则抛出的列表是普通的java7 ArrayList,该List在循环中未修改,并且在上述方法中是本地的-不会在其他任何地方传递.

每次进行api调用之前,始终引发异常,直到服务器重新启动-然后异常停止.

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.next(ArrayList.java:837)
    at org.apache.http.impl.cookie.BestMatchSpec.formatCookies(BestMatchSpec.java:175)
    at org.apache.http.client.protocol.RequestAddCookies.process(RequestAddCookies.java:174)
    at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:131)

代码在下面,但很难在IDE外部阅读,这里是进行调用的GrepCode,请参见matchCookies没有传递到线程范围之外.

BestMatchSpec.formatCookies不会修改cookie列表:

public List<Header> formatCookies(final List<Cookie> cookies) {
    Args.notNull(cookies, "List of cookies");
    int version = Integer.MAX_VALUE;
    boolean isSetCookie2 = true;
    for (final Cookie cookie: cookies) {
        if (!(cookie instanceof SetCookie2)) {
            isSetCookie2 = false;
        }
        if (cookie.getVersion() < version) {
            version = cookie.getVersion();
        }
    }

调用方法RequestAddCookies.process构造该列表,并且不使cookie列表可用于其他线程.

public void process(final HttpRequest request, final HttpContext context)
        throws HttpException, IOException {
...
    // Find cookies matching the given origin
    final List<Cookie> matchedCookies = new ArrayList<Cookie>();
    final Date now = new Date();
    for (final Cookie cookie : cookies) {
        if (!cookie.isExpired(now)) {
            if (cookieSpec.match(cookie, cookieOrigin)) {
                if (this.log.isDebugEnabled()) {
                    this.log.debug("Cookie " + cookie + " match " + cookieOrigin);
                }
                matchedCookies.add(cookie);
            }
        } else {
            if (this.log.isDebugEnabled()) {
                this.log.debug("Cookie " + cookie + " expired");
            }
        }
    }
    // Generate Cookie request headers
    if (!matchedCookies.isEmpty()) {
        final List<Header> headers = cookieSpec.formatCookies(matchedCookies);
...
}

我想念什么吗?

解决方法:

感谢@guido在apache上指出了这个问题.这是由于java7u60中修复的JIT编译器存在错误所致.该代码应该不能产生ConcurrentModificationException.

HttpClient报告:
https://issues.apache.org/jira/browse/HTTPCLIENT-1173

Java错误:
http://bugs.java.com/view_bug.do?bug_id=8021898

测试重现错误:
https://github.com/rholder/jvm-loop-unswitching-bug

标签:concurrency,java-7,java
来源: https://codeday.me/bug/20191121/2053773.html