[Fix] Fixed concurrent modification exception in SynchronizedCollections

This commit is contained in:
Robert von Burg 2020-05-19 11:16:53 +02:00
parent af8ac81a18
commit a0b24f74a5
4 changed files with 555 additions and 73 deletions

View File

@ -29,7 +29,7 @@ public class SynchronizedCollections {
SynchronizedMapOfLists(MapOfLists<T, U> m) {
this.m = m;
this.mutex = new Object();
this.mutex = this;
}
@Override
@ -174,7 +174,7 @@ public class SynchronizedCollections {
SynchronizedMapOfMaps(MapOfMaps<T, U, V> m) {
this.m = m;
this.mutex = new Object();
this.mutex = this;
}
@Override
@ -341,7 +341,7 @@ public class SynchronizedCollections {
public SynchronizedMapOfSets(MapOfSets<T, U> m) {
this.m = m;
this.mutex = new Object();
this.mutex = this;
}
@Override
@ -507,35 +507,35 @@ public class SynchronizedCollections {
@Override
public int size() {
synchronized (mutex) {
synchronized (this.mutex) {
return c.size();
}
}
@Override
public boolean isEmpty() {
synchronized (mutex) {
synchronized (this.mutex) {
return c.isEmpty();
}
}
@Override
public boolean contains(Object o) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.contains(o);
}
}
@Override
public Object[] toArray() {
synchronized (mutex) {
synchronized (this.mutex) {
return c.toArray();
}
}
@Override
public <T> T[] toArray(T[] a) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.toArray(a);
}
}
@ -547,70 +547,70 @@ public class SynchronizedCollections {
@Override
public boolean add(E e) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.add(e);
}
}
@Override
public boolean remove(Object o) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.remove(o);
}
}
@Override
public boolean containsAll(Collection<?> coll) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.containsAll(coll);
}
}
@Override
public boolean addAll(Collection<? extends E> coll) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.addAll(coll);
}
}
@Override
public boolean removeAll(Collection<?> coll) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.removeAll(coll);
}
}
@Override
public boolean retainAll(Collection<?> coll) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.retainAll(coll);
}
}
@Override
public void clear() {
synchronized (mutex) {
synchronized (this.mutex) {
c.clear();
}
}
@Override
public String toString() {
synchronized (mutex) {
synchronized (this.mutex) {
return c.toString();
}
}
@Override
public void forEach(Consumer<? super E> consumer) {
synchronized (mutex) {
synchronized (this.mutex) {
c.forEach(consumer);
}
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
synchronized (mutex) {
synchronized (this.mutex) {
return c.removeIf(filter);
}
}
@ -631,7 +631,7 @@ public class SynchronizedCollections {
}
private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {
synchronized (this.mutex) {
s.defaultWriteObject();
}
}
@ -650,63 +650,63 @@ public class SynchronizedCollections {
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) {
synchronized (this.mutex) {
return list.equals(o);
}
}
@Override
public int hashCode() {
synchronized (mutex) {
synchronized (this.mutex) {
return list.hashCode();
}
}
@Override
public E get(int index) {
synchronized (mutex) {
synchronized (this.mutex) {
return list.get(index);
}
}
@Override
public E set(int index, E element) {
synchronized (mutex) {
synchronized (this.mutex) {
return list.set(index, element);
}
}
@Override
public void add(int index, E element) {
synchronized (mutex) {
synchronized (this.mutex) {
list.add(index, element);
}
}
@Override
public E remove(int index) {
synchronized (mutex) {
synchronized (this.mutex) {
return list.remove(index);
}
}
@Override
public int indexOf(Object o) {
synchronized (mutex) {
synchronized (this.mutex) {
return list.indexOf(o);
}
}
@Override
public int lastIndexOf(Object o) {
synchronized (mutex) {
synchronized (this.mutex) {
return list.lastIndexOf(o);
}
}
@Override
public boolean addAll(int index, Collection<? extends E> c) {
synchronized (mutex) {
synchronized (this.mutex) {
return list.addAll(index, c);
}
}
@ -723,21 +723,21 @@ public class SynchronizedCollections {
@Override
public List<E> subList(int fromIndex, int toIndex) {
synchronized (mutex) {
return new SynchronizedList<>(list.subList(fromIndex, toIndex), mutex);
synchronized (this.mutex) {
return new SynchronizedList<>(list.subList(fromIndex, toIndex), this.mutex);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
synchronized (mutex) {
synchronized (this.mutex) {
list.replaceAll(operator);
}
}
@Override
public void sort(Comparator<? super E> c) {
synchronized (mutex) {
synchronized (this.mutex) {
list.sort(c);
}
}
@ -753,14 +753,14 @@ public class SynchronizedCollections {
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) {
synchronized (this.mutex) {
return c.equals(o);
}
}
@Override
public int hashCode() {
synchronized (mutex) {
synchronized (this.mutex) {
return c.hashCode();
}
}
@ -777,42 +777,42 @@ public class SynchronizedCollections {
@Override
public Comparator<? super E> comparator() {
synchronized (mutex) {
synchronized (this.mutex) {
return ss.comparator();
}
}
@Override
public SortedSet<E> subSet(E fromElement, E toElement) {
synchronized (mutex) {
return new SynchronizedSortedSet<>(ss.subSet(fromElement, toElement), mutex);
synchronized (this.mutex) {
return new SynchronizedSortedSet<>(ss.subSet(fromElement, toElement), this.mutex);
}
}
@Override
public SortedSet<E> headSet(E toElement) {
synchronized (mutex) {
return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex);
synchronized (this.mutex) {
return new SynchronizedSortedSet<>(ss.headSet(toElement), this.mutex);
}
}
@Override
public SortedSet<E> tailSet(E fromElement) {
synchronized (mutex) {
return new SynchronizedSortedSet<>(ss.tailSet(fromElement), mutex);
synchronized (this.mutex) {
return new SynchronizedSortedSet<>(ss.tailSet(fromElement), this.mutex);
}
}
@Override
public E first() {
synchronized (mutex) {
synchronized (this.mutex) {
return ss.first();
}
}
@Override
public E last() {
synchronized (mutex) {
synchronized (this.mutex) {
return ss.last();
}
}
@ -829,55 +829,55 @@ public class SynchronizedCollections {
}
public int size() {
synchronized (mutex) {
synchronized (this.mutex) {
return m.size();
}
}
public boolean isEmpty() {
synchronized (mutex) {
synchronized (this.mutex) {
return m.isEmpty();
}
}
public boolean containsKey(Object key) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.containsKey(key);
}
}
public boolean containsValue(Object value) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.containsValue(value);
}
}
public V get(Object key) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.get(key);
}
}
public V put(K key, V value) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.put(key, value);
}
}
public V remove(Object key) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.remove(key);
}
}
public void putAll(Map<? extends K, ? extends V> map) {
synchronized (mutex) {
synchronized (this.mutex) {
m.putAll(map);
}
}
public void clear() {
synchronized (mutex) {
synchronized (this.mutex) {
m.clear();
}
}
@ -887,25 +887,25 @@ public class SynchronizedCollections {
private transient Collection<V> values;
public Set<K> keySet() {
synchronized (mutex) {
synchronized (this.mutex) {
if (keySet == null)
keySet = new SynchronizedSet<>(m.keySet(), mutex);
keySet = new SynchronizedSet<>(m.keySet(), this.mutex);
return keySet;
}
}
public Set<Map.Entry<K, V>> entrySet() {
synchronized (mutex) {
synchronized (this.mutex) {
if (entrySet == null)
entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
entrySet = new SynchronizedSet<>(m.entrySet(), this.mutex);
return entrySet;
}
}
public Collection<V> values() {
synchronized (mutex) {
synchronized (this.mutex) {
if (values == null)
values = new SynchronizedCollection<>(m.values(), mutex);
values = new SynchronizedCollection<>(m.values(), this.mutex);
return values;
}
}
@ -913,102 +913,102 @@ public class SynchronizedCollections {
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) {
synchronized (this.mutex) {
return m.equals(o);
}
}
public int hashCode() {
synchronized (mutex) {
synchronized (this.mutex) {
return m.hashCode();
}
}
public String toString() {
synchronized (mutex) {
synchronized (this.mutex) {
return m.toString();
}
}
@Override
public V getOrDefault(Object k, V defaultValue) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.getOrDefault(k, defaultValue);
}
}
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
synchronized (mutex) {
synchronized (this.mutex) {
m.forEach(action);
}
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
synchronized (mutex) {
synchronized (this.mutex) {
m.replaceAll(function);
}
}
@Override
public V putIfAbsent(K key, V value) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.putIfAbsent(key, value);
}
}
@Override
public boolean remove(Object key, Object value) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.remove(key, value);
}
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.replace(key, oldValue, newValue);
}
}
@Override
public V replace(K key, V value) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.replace(key, value);
}
}
@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.computeIfAbsent(key, mappingFunction);
}
}
@Override
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.computeIfPresent(key, remappingFunction);
}
}
@Override
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.compute(key, remappingFunction);
}
}
@Override
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {
synchronized (this.mutex) {
return m.merge(key, value, remappingFunction);
}
}
private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {
synchronized (this.mutex) {
s.defaultWriteObject();
}
}

View File

@ -0,0 +1,160 @@
package li.strolch.utils.collections;
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfLists;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SynchronizedMapOfListsTest {
private static final Logger logger = LoggerFactory.getLogger(SynchronizedMapOfListsTest.class);
private ExecutorService executorService;
@Before
public void before() {
this.executorService = Executors.newCachedThreadPool();
}
@Test
public void shouldForEach() throws ExecutionException, InterruptedException {
MapOfLists<String, String> mapOfLists = buildMapOfLists();
AtomicBoolean run = new AtomicBoolean(false);
Callable<Boolean> addTask = () -> addToMap(mapOfLists, run);
Callable<Boolean> iterateTask = () -> {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
mapOfLists.forEach((s, list) -> list.forEach(s1 -> logger.info(s + " " + s1)));
mapOfLists.getList("Resource").forEach(s1 -> logger.info(" " + s1));
}
return true;
};
runTest(addTask, iterateTask, run);
}
@Test
public void shouldIterate() throws ExecutionException, InterruptedException {
MapOfLists<String, String> mapOfLists = buildMapOfLists();
AtomicBoolean run = new AtomicBoolean(false);
Callable<Boolean> addTask = () -> addToMap(mapOfLists, run);
Callable<Boolean> iterateTask = () -> {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
Set<String> types = mapOfLists.keySet();
for (String type : types) {
synchronized (mapOfLists) {
for (String id : mapOfLists.getList(type)) {
logger.info(type + " " + id);
}
}
}
synchronized (mapOfLists) {
List<String> resources = mapOfLists.getList("Resource");
for (String value : resources) {
logger.info("Resource: value: " + value);
}
}
}
return true;
};
runTest(addTask, iterateTask, run);
}
private void runTest(Callable<Boolean> addTask, Callable<Boolean> iterateTask, AtomicBoolean run)
throws InterruptedException, ExecutionException {
Future<Boolean> task0 = this.executorService.submit(addTask);
Future<Boolean> task1 = this.executorService.submit(iterateTask);
Future<Boolean> task2 = this.executorService.submit(iterateTask);
Future<Boolean> task3 = this.executorService.submit(iterateTask);
Future<Boolean> task4 = this.executorService.submit(iterateTask);
Future<Boolean> task5 = this.executorService.submit(iterateTask);
run.set(true);
Thread.sleep(1000L);
run.set(false);
Boolean result0 = task0.get();
Boolean result1 = task1.get();
Boolean result2 = task2.get();
Boolean result3 = task3.get();
Boolean result4 = task4.get();
Boolean result5 = task5.get();
assertTrue(result0);
assertTrue(result1);
assertTrue(result2);
assertTrue(result3);
assertTrue(result4);
assertTrue(result5);
}
private Boolean addToMap(MapOfLists<String, String> mapOfLists, AtomicBoolean run) {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
addElement(mapOfLists, "Resource", UUID.randomUUID().toString());
addElement(mapOfLists, "Resource", UUID.randomUUID().toString());
addElement(mapOfLists, "Order", UUID.randomUUID().toString());
addElement(mapOfLists, "Order", UUID.randomUUID().toString());
addElement(mapOfLists, "Order", UUID.randomUUID().toString());
addElement(mapOfLists, "Activity", UUID.randomUUID().toString());
addElement(mapOfLists, "Activity", UUID.randomUUID().toString());
mapOfLists.removeElement("Resource", "Ball");
mapOfLists.removeElement("Order", "ToStock");
mapOfLists.removeElement("Activity", "ToStock");
}
return true;
}
private void addElement(MapOfLists<String, String> mapOfLists, String type, String id) {
logger.info("Adding " + type + " " + id);
mapOfLists.addElement(type, id);
}
private MapOfLists<String, String> buildMapOfLists() {
MapOfLists<String, String> mapOfLists = synchronizedMapOfLists(new MapOfLists<>(true));
mapOfLists.addElement("Resource", "Ball");
mapOfLists.addElement("Resource", "Car");
mapOfLists.addElement("Order", "StockOrder");
mapOfLists.addElement("Order", "ToStock");
mapOfLists.addElement("Order", "FromStock");
mapOfLists.addElement("Activity", "FromStock");
mapOfLists.addElement("Activity", "ToStock");
assertEquals(Arrays.asList("Ball", "Car"), mapOfLists.getList("Resource"));
assertNull(mapOfLists.getList("xxx"));
return mapOfLists;
}
}

View File

@ -0,0 +1,162 @@
package li.strolch.utils.collections;
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfMaps;
import static org.junit.Assert.*;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SynchronizedMapOfMapsTest {
private static final Logger logger = LoggerFactory.getLogger(SynchronizedMapOfMapsTest.class);
private ExecutorService executorService;
@Before
public void before() {
this.executorService = Executors.newCachedThreadPool();
}
@Test
public void shouldForEach() throws ExecutionException, InterruptedException {
MapOfMaps<String, String, String> mapOfMaps = buildMapOfMaps();
AtomicBoolean run = new AtomicBoolean(false);
Callable<Boolean> addTask = () -> addToMap(mapOfMaps, run);
Callable<Boolean> iterateTask = () -> {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
mapOfMaps.forEach(
(s, subTypeMap) -> subTypeMap.forEach((s1, s2) -> logger.info(s + " " + s1 + " " + s2)));
mapOfMaps.getMap("Resource").forEach((s1, s2) -> logger.info(" " + s1 + " " + s2));
}
return true;
};
runTest(addTask, iterateTask, run);
}
@Test
public void shouldIterate() throws ExecutionException, InterruptedException {
MapOfMaps<String, String, String> mapOfMaps = buildMapOfMaps();
AtomicBoolean run = new AtomicBoolean(false);
Callable<Boolean> addTask = () -> addToMap(mapOfMaps, run);
Callable<Boolean> iterateTask = () -> {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
Set<String> types = mapOfMaps.keySet();
for (String type : types) {
Map<String, String> subTypeMap = mapOfMaps.getMap(type);
Set<String> subTypes = subTypeMap.keySet();
synchronized (mapOfMaps) {
for (String subType : subTypes) {
logger.info(type + " " + subType + " " + mapOfMaps.getElement(type, subType));
}
}
}
synchronized (mapOfMaps) {
Map<String, String> resources = mapOfMaps.getMap("Resource");
for (String value : resources.values()) {
logger.info("Resource: value: " + value);
}
}
}
return true;
};
runTest(addTask, iterateTask, run);
}
private void runTest(Callable<Boolean> addTask, Callable<Boolean> iterateTask, AtomicBoolean run)
throws InterruptedException, ExecutionException {
Future<Boolean> task0 = this.executorService.submit(addTask);
Future<Boolean> task1 = this.executorService.submit(iterateTask);
Future<Boolean> task2 = this.executorService.submit(iterateTask);
Future<Boolean> task3 = this.executorService.submit(iterateTask);
Future<Boolean> task4 = this.executorService.submit(iterateTask);
Future<Boolean> task5 = this.executorService.submit(iterateTask);
run.set(true);
Thread.sleep(1000L);
run.set(false);
Boolean result0 = task0.get();
Boolean result1 = task1.get();
Boolean result2 = task2.get();
Boolean result3 = task3.get();
Boolean result4 = task4.get();
Boolean result5 = task5.get();
assertTrue(result0);
assertTrue(result1);
assertTrue(result2);
assertTrue(result3);
assertTrue(result4);
assertTrue(result5);
}
private Boolean addToMap(MapOfMaps<String, String, String> mapOfMaps, AtomicBoolean run) {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
addElement(mapOfMaps, "Resource", "Ball", UUID.randomUUID().toString());
addElement(mapOfMaps, "Resource", "Car", UUID.randomUUID().toString());
addElement(mapOfMaps, "Order", "StockOrder", UUID.randomUUID().toString());
addElement(mapOfMaps, "Order", "ToStock", UUID.randomUUID().toString());
addElement(mapOfMaps, "Order", "FromStock", UUID.randomUUID().toString());
addElement(mapOfMaps, "Activity", "FromStock", UUID.randomUUID().toString());
addElement(mapOfMaps, "Activity", "ToStock", UUID.randomUUID().toString());
mapOfMaps.removeElement("Resource", "Ball");
mapOfMaps.removeElement("Order", "ToStock");
mapOfMaps.removeElement("Activity", "ToStock");
}
return true;
}
private void addElement(MapOfMaps<String, String, String> mapOfMaps, String type, String subType, String id) {
logger.info("Adding " + type + " " + subType + " " + id);
mapOfMaps.addElement(type, subType, id);
}
private MapOfMaps<String, String, String> buildMapOfMaps() {
MapOfMaps<String, String, String> mapOfMaps = synchronizedMapOfMaps(new MapOfMaps<>(true));
mapOfMaps.addElement("Resource", "Ball", "yellow");
mapOfMaps.addElement("Resource", "Car", "car1");
mapOfMaps.addElement("Order", "StockOrder", "stockOrder1");
mapOfMaps.addElement("Order", "ToStock", "toStock1");
mapOfMaps.addElement("Order", "FromStock", "fromStock1");
mapOfMaps.addElement("Activity", "FromStock", "fromStock1");
mapOfMaps.addElement("Activity", "ToStock", "toStock1");
assertEquals("yellow", mapOfMaps.getElement("Resource", "Ball"));
assertNull(mapOfMaps.getMap("xxx"));
return mapOfMaps;
}
}

View File

@ -0,0 +1,160 @@
package li.strolch.utils.collections;
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfSets;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SynchronizedMapOfSetsTest {
private static final Logger logger = LoggerFactory.getLogger(SynchronizedMapOfSetsTest.class);
private ExecutorService executorService;
@Before
public void before() {
this.executorService = Executors.newCachedThreadPool();
}
@Test
public void shouldForEach() throws ExecutionException, InterruptedException {
MapOfSets<String, String> mapOfSets = buildMapOfSets();
AtomicBoolean run = new AtomicBoolean(false);
Callable<Boolean> addTask = () -> addToMap(mapOfSets, run);
Callable<Boolean> iterateTask = () -> {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
mapOfSets.forEach((s, list) -> list.forEach(s1 -> logger.info(s + " " + s1)));
mapOfSets.getSet("Resource").forEach(s1 -> logger.info(" " + s1));
}
return true;
};
runTest(addTask, iterateTask, run);
}
@Test
public void shouldIterate() throws ExecutionException, InterruptedException {
MapOfSets<String, String> mapOfSets = buildMapOfSets();
AtomicBoolean run = new AtomicBoolean(false);
Callable<Boolean> addTask = () -> addToMap(mapOfSets, run);
Callable<Boolean> iterateTask = () -> {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
Set<String> types = mapOfSets.keySet();
for (String type : types) {
synchronized (mapOfSets) {
for (String id : mapOfSets.getSet(type)) {
logger.info(type + " " + id);
}
}
}
synchronized (mapOfSets) {
Set<String> resources = mapOfSets.getSet("Resource");
for (String value : resources) {
logger.info("Resource: value: " + value);
}
}
}
return true;
};
runTest(addTask, iterateTask, run);
}
private void runTest(Callable<Boolean> addTask, Callable<Boolean> iterateTask, AtomicBoolean run)
throws InterruptedException, ExecutionException {
Future<Boolean> task0 = this.executorService.submit(addTask);
Future<Boolean> task1 = this.executorService.submit(iterateTask);
Future<Boolean> task2 = this.executorService.submit(iterateTask);
Future<Boolean> task3 = this.executorService.submit(iterateTask);
Future<Boolean> task4 = this.executorService.submit(iterateTask);
Future<Boolean> task5 = this.executorService.submit(iterateTask);
run.set(true);
Thread.sleep(1000L);
run.set(false);
Boolean result0 = task0.get();
Boolean result1 = task1.get();
Boolean result2 = task2.get();
Boolean result3 = task3.get();
Boolean result4 = task4.get();
Boolean result5 = task5.get();
assertTrue(result0);
assertTrue(result1);
assertTrue(result2);
assertTrue(result3);
assertTrue(result4);
assertTrue(result5);
}
private Boolean addToMap(MapOfSets<String, String> mapOfSets, AtomicBoolean run) {
for (; ; ) {
if (run.get())
break;
}
while (run.get()) {
addElement(mapOfSets, "Resource", UUID.randomUUID().toString());
addElement(mapOfSets, "Resource", UUID.randomUUID().toString());
addElement(mapOfSets, "Order", UUID.randomUUID().toString());
addElement(mapOfSets, "Order", UUID.randomUUID().toString());
addElement(mapOfSets, "Order", UUID.randomUUID().toString());
addElement(mapOfSets, "Activity", UUID.randomUUID().toString());
addElement(mapOfSets, "Activity", UUID.randomUUID().toString());
mapOfSets.removeElement("Resource", "Ball");
mapOfSets.removeElement("Order", "ToStock");
mapOfSets.removeElement("Activity", "ToStock");
}
return true;
}
private void addElement(MapOfSets<String, String> mapOfSets, String type, String id) {
logger.info("Adding " + type + " " + id);
mapOfSets.addElement(type, id);
}
private MapOfSets<String, String> buildMapOfSets() {
MapOfSets<String, String> mapOfSets = synchronizedMapOfSets(new MapOfSets<>(true));
mapOfSets.addElement("Resource", "Ball");
mapOfSets.addElement("Resource", "Car");
mapOfSets.addElement("Order", "StockOrder");
mapOfSets.addElement("Order", "ToStock");
mapOfSets.addElement("Order", "FromStock");
mapOfSets.addElement("Activity", "FromStock");
mapOfSets.addElement("Activity", "ToStock");
assertEquals(new HashSet<>(Arrays.asList("Ball", "Car")), mapOfSets.getSet("Resource"));
assertNull(mapOfSets.getSet("xxx"));
return mapOfSets;
}
}