FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin lynx.local 16.0.0 Darwin Kernel Version 16.0.0: Mon Aug 29 17:56:20 PDT 2016; root:xnu-3789.1.32~3/RELEASE_X86_64 x86_64
A DESCRIPTION OF THE PROBLEM :
Calling clear() on a ConcurrentSkipListSet while also calling add() can cause the set to become unusable.
It may appear isEmpty() with size()==0, yet still contain elements per contains() and add().
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the test program noted below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The program should not terminate.
ACTUAL -
$ java TestSet
**** An empty set contains 'c'! (Iteration 79)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentSkipListSet;
public class TestSet {
public static void main(String[] args) {
int i = 0;
while (true) {
i++;
ConcurrentSkipListSet<String> set = new ConcurrentSkipListSet<>();
set.add("a");
CompletableFuture<Void> future = CompletableFuture.runAsync(
() -> set.clear());
set.add("b");
set.add("c");
future.join();
if (set.isEmpty() && set.contains("c")) {
System.out.println(
"**** An empty set contains 'c'! (Iteration " + i + ")");
break;
}
}
}
}
---------- END SOURCE ----------