Reputation: 1298
I have the following code to form a url, but some clients have reported exception at the for loop. 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);
}
requestParam is modified in RequestTask. why would it fail?
Upvotes: 0
Views: 313
Reputation: 3377
After your comments, I suspect you should synchronize on the requestParams
object, not on this
.
The async task does not have a reference to the object that is iterating, so they are not locking on the same object, which is virtually the same as not synchronizing at all.
Make sure both classes synchronize on the same reference of the same object!
PS: if both classes do a synchronized(this), they are effectively synchronizing on different object instances.
Upvotes: 2
Reputation: 1742
When using an Iterator
over an ordered set you must use iterator.remove()
instead of <? extends Collection>.remove()
. The latter yields a ConcurrentModificationException
. If you are modifying requestParams
in another thread and you must use the Iterator
either have a field private Iterator iter
in your class and provide a getIterator()
method and perform the necessary null checks.
Upvotes: 0