-
Bug
-
Resolution: Cannot Reproduce
-
P4
-
None
-
21, 24, 25
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
Java HotSpot(TM) 64-Bit Server VM (21.0.1+12-LTS-29) for bsd-amd64 JRE (21.0.1+12-LTS-29), built on 2023-10-05T13:27:09Z by "mach5one" with clang Apple LLVM 12.0.0 (clang-1200.0.32.29)
A DESCRIPTION OF THE PROBLEM :
ConcurrentHashMap.removeIf() would run into infinite loop if add and remove operation happened at same time
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
reproduce code:
class Scratch {
public static void main(String[] args) throws InterruptedException {
var map = new ConcurrentHashMap<Integer, Optional<Integer>>();
try (ExecutorService executor = Executors.newWorkStealingPool()) {
Future<?> addTask =
executor.submit(() -> IntStream.range(0, 1_000_000_000)
.forEach(i -> map.put(i, i % 2 == 0 ? Optional.of(i) : Optional.empty())));
Future<Boolean> removeTask =
executor.submit(() -> map.entrySet().removeIf(e -> e.getValue().isEmpty()));
removeTask.wait();
}
System.out.println("Program Finished");
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the expected result is the program should complete two future tasks and print out "Program Finished"
ACTUAL -
the program stuck in the loop and never exit.
---------- BEGIN SOURCE ----------
class Scratch {
public static void main(String[] args) throws InterruptedException {
var map = new ConcurrentHashMap<Integer, Optional<Integer>>();
try (ExecutorService executor = Executors.newWorkStealingPool()) {
Future<?> addTask =
executor.submit(() -> IntStream.range(0, 1_000_000_000)
.forEach(i -> map.put(i, i % 2 == 0 ? Optional.of(i) : Optional.empty())));
Future<Boolean> removeTask =
executor.submit(() -> map.entrySet().removeIf(e -> e.getValue().isEmpty()));
removeTask.wait();
}
System.out.println("Program Finished");
}
}
---------- END SOURCE ----------
Java HotSpot(TM) 64-Bit Server VM (21.0.1+12-LTS-29) for bsd-amd64 JRE (21.0.1+12-LTS-29), built on 2023-10-05T13:27:09Z by "mach5one" with clang Apple LLVM 12.0.0 (clang-1200.0.32.29)
A DESCRIPTION OF THE PROBLEM :
ConcurrentHashMap.removeIf() would run into infinite loop if add and remove operation happened at same time
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
reproduce code:
class Scratch {
public static void main(String[] args) throws InterruptedException {
var map = new ConcurrentHashMap<Integer, Optional<Integer>>();
try (ExecutorService executor = Executors.newWorkStealingPool()) {
Future<?> addTask =
executor.submit(() -> IntStream.range(0, 1_000_000_000)
.forEach(i -> map.put(i, i % 2 == 0 ? Optional.of(i) : Optional.empty())));
Future<Boolean> removeTask =
executor.submit(() -> map.entrySet().removeIf(e -> e.getValue().isEmpty()));
removeTask.wait();
}
System.out.println("Program Finished");
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the expected result is the program should complete two future tasks and print out "Program Finished"
ACTUAL -
the program stuck in the loop and never exit.
---------- BEGIN SOURCE ----------
class Scratch {
public static void main(String[] args) throws InterruptedException {
var map = new ConcurrentHashMap<Integer, Optional<Integer>>();
try (ExecutorService executor = Executors.newWorkStealingPool()) {
Future<?> addTask =
executor.submit(() -> IntStream.range(0, 1_000_000_000)
.forEach(i -> map.put(i, i % 2 == 0 ? Optional.of(i) : Optional.empty())));
Future<Boolean> removeTask =
executor.submit(() -> map.entrySet().removeIf(e -> e.getValue().isEmpty()));
removeTask.wait();
}
System.out.println("Program Finished");
}
}
---------- END SOURCE ----------