Skip to content

Commit bc3e168

Browse files
Fix thread-unsafe clear()
1 parent c7d178e commit bc3e168

File tree

1 file changed

+18
-12
lines changed
  • src/main/java/com/amazonaws/services/dynamodbv2/datamodeling/internal

1 file changed

+18
-12
lines changed

src/main/java/com/amazonaws/services/dynamodbv2/datamodeling/internal/LRUCache.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
*/
1515
package com.amazonaws.services.dynamodbv2.datamodeling.internal;
1616

17-
import java.util.AbstractMap.SimpleImmutableEntry;
17+
import com.amazonaws.annotation.ThreadSafe;
18+
19+
import java.util.ArrayList;
1820
import java.util.Collections;
21+
import java.util.Iterator;
1922
import java.util.LinkedHashMap;
23+
import java.util.List;
2024
import java.util.Map;
21-
import java.util.Set;
22-
import java.util.TreeSet;
23-
24-
import com.amazonaws.annotation.ThreadSafe;
25+
import java.util.Map.Entry;
2526

2627
/**
2728
* A bounded cache that has a LRU eviction policy when the cache is full.
@@ -98,11 +99,16 @@ public void clear() {
9899
// The more complicated logic is to ensure that the listener is
99100
// actually called for all entries.
100101
if (listener != null) {
101-
Set<String> keys = new TreeSet<String>(map.keySet());
102-
for (String key : keys) {
103-
T val = map.get(key);
104-
listener.onRemoval(new SimpleImmutableEntry<String, T>(key, val));
105-
map.remove(key);
102+
List<Entry<String, T>> removedEntries = new ArrayList<Entry<String, T>>();
103+
synchronized (map) {
104+
Iterator<Entry<String, T>> it = map.entrySet().iterator();
105+
while(it.hasNext()) {
106+
removedEntries.add(it.next());
107+
it.remove();
108+
}
109+
}
110+
for (Entry<String, T> entry : removedEntries) {
111+
listener.onRemoval(entry);
106112
}
107113
} else {
108114
map.clear();
@@ -126,7 +132,7 @@ private LRUHashMap(final int maxSize, final RemovalListener<T> listener) {
126132
}
127133

128134
@Override
129-
protected boolean removeEldestEntry(final Map.Entry<String, T> eldest) {
135+
protected boolean removeEldestEntry(final Entry<String, T> eldest) {
130136
if (size() > maxSize) {
131137
if (listener != null) {
132138
listener.onRemoval(eldest);
@@ -138,6 +144,6 @@ protected boolean removeEldestEntry(final Map.Entry<String, T> eldest) {
138144
}
139145

140146
public static interface RemovalListener<T> {
141-
public void onRemoval(Map.Entry<String, T> entry);
147+
public void onRemoval(Entry<String, T> entry);
142148
}
143149
}

0 commit comments

Comments
 (0)