*
* Thanks to Ivan Koblik (http://koblik.blogspot.com) for contributing initial code and idea
*/
@Test
public void testConcurrentAddRemove() {
final IConcurrentSet testSet = createSet();
// a set of unique integers that will stay permanently in the test set
final List permanentObjects = new ArrayList();
// a set of objects that will be added and removed at random to the test set to force rehashing
final List volatileObjects = new ArrayList();
permanentObjects.addAll(createWithRandomIntegers(80, null));
volatileObjects.addAll(createWithRandomIntegers(10000, permanentObjects));
final CopyOnWriteArraySet missing = new CopyOnWriteArraySet();
final int mutatorThreshold = 1000;
// Add elements that will not be touched by the constantly running mutating thread
for (Object permanent : permanentObjects) {
testSet.add(permanent);
}
// Adds and removes items
// thus forcing constant rehashing of the backing hashtable
Runnable rehasher = new Runnable() {
public void run() {
Random rand = new Random();
for(int times = 0; times < 1000 ; times++){
HashSet elements = new HashSet(mutatorThreshold);
for (int i = 0; i < mutatorThreshold; i++) {
Object volatileObject = volatileObjects.get(Math.abs(rand.nextInt()) % volatileObjects.size());
testSet.add(volatileObject);
elements.add(volatileObject);
}
for (Object volObj : elements) {
testSet.remove(volObj);
}
}
};
};
Runnable lookup = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
for (Object permanent : permanentObjects) {
// permanent items are never touched,
// --> set.contains(j) should always return true
if(!testSet.contains(permanent))
missing.add(permanent);
}
}
}
};