我有以下代码来形成一个url,但有些客户端在for循环中报告了异常。 java.util.ConcurrentModificationException at java.util.ArrayList $ ArrayListIterator.next(ArrayList.java:573)
List<NameValuePair> requestParams = adRequest
.createRequestParamsList(view.getContext());
RequestTask currentTask = new RequestTask(this,
view.getUserAgent(), view.getContext(), keyCode);
try {
currentTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
baseRequestUrl + Request.REQ_URI, requestParams);
} catch (Exception e) {
}
String debugUrl = "";
synchronized (this) {
debugUrl = baseRequestUrl + Request.REQ_URI + "?";
for (Iterator<NameValuePair> iterator = requestParams.iterator(); iterator.hasNext();) {
NameValuePair nvp = iterator.next();
debugUrl = debugUrl + nvp.getName() + "=" + nvp.getValue() + "&";
}
debugUrl = debugUrl.substring(0, debugUrl.length() - 1);
}
在RequestTask中修改了requestParam。为什么会失败?
答案 0 :(得分:2)
发表评论后,我怀疑您应该在this
对象上进行同步,而不是.datum()
。
异步任务没有对正在迭代的对象的引用,因此它们不会锁定在同一个对象上,这实际上与完全不同步一样。
确保两个类在同一个对象的同一引用上同步!
PS:如果两个类都进行了同步(this),它们实际上是在不同的对象实例上进行同步。
答案 1 :(得分:0)
在有序集上使用Iterator
时,您必须使用iterator.remove()
代替<? extends Collection>.remove()
。后者产生ConcurrentModificationException
。如果您要修改另一个主题中的requestParams
,并且必须使用Iterator
在您的类中有一个字段private Iterator iter
,并提供getIterator()
方法并执行必要的空检查。