Reputation: 13230
In the following code sample, I don't understand why foo method throws ConcurrentModificationException. Please help!
private void foo() {
synchronized (map) {
if (map != null && !map.isEmpty()) {
Set<String> it = map.keySet();
ArrayList<String> delArray = new ArrayList<>();
for (String key : it) {
MapItem mapItem = map.get(key);
if (mapItem != null) {
long wakeTime = System.currentTimeMillis() - mapItem.getTimestamp();
if (wakeTime > MY_THRESHOLD) {
if (mapItem.getLock() != null) {
mapItem.getLock().release();
}
delArray.add(key);
}
}
}
if (!delArray.isEmpty()) {
for (String key : delArray) {
map.remove(key);
}
}
}
}
}
I am getting exception on "for (String key : it) {" line
private static class MapItem {
private PowerManager.WakeLock lock;
private long timestamp;
public MapItem(PowerManager.WakeLock lock, long timestamp) {
this.lock = lock;
this.timestamp = timestamp;
}
public PowerManager.WakeLock getLock() {
return lock;
}
public long getTimestamp() {
return timestamp;
}
}
Upvotes: 2
Views: 703
Reputation: 952
I think you didn't put all your code here. Why the constructor if MapItem is WakeLockItem, and what
mapItem.getLock().release();
does? If I remove all PowerManager.WakeLock
related code, I can execute it.
private static class MapItem {
private long timestamp;
public MapItem(long timestamp) {
this.timestamp = timestamp;
}
public long getTimestamp() {
return timestamp;
}
}
private Map<String, MapItem> map = new HashMap<>();
private void foo() {
synchronized (map) {
if (map != null && !map.isEmpty()) {
Set<String> it = map.keySet();
ArrayList<String> delArray = new ArrayList<>();
for (String key : it) {
MapItem mapItem = map.get(key);
if (mapItem != null) {
long wakeTime = System.currentTimeMillis() - mapItem.getTimestamp();
if (wakeTime > 0) {
delArray.add(key);
}
}
}
if (!delArray.isEmpty()) {
for (String key : delArray) {
map.remove(key);
}
}
}
}
}
Upvotes: 0
Reputation: 18792
You are trying to change map
while iterating over it, which is not allowed.
ConcurrentModificationException:
If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception
Upvotes: 1