Created
November 13, 2021 03:05
-
-
Save alcatrazEscapee/cc25cd3ba257e8624d762ff491c9d6bb to your computer and use it in GitHub Desktop.
Race condition involving `BiMap.put` and `BiMap.get`, where `get` returns `null` despite no null ever being present in the map.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package bi_map_race_condition; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.Executors; | |
import com.google.common.collect.BiMap; | |
import com.google.common.collect.HashBiMap; | |
public class BiMapRaceCondition | |
{ | |
public static void main(String[] args) | |
{ | |
// The map in question uses registry keys, but those are ultimately equals-dependent on strings | |
// Pre-load it a bit | |
final BiMap<String, Object> map = HashBiMap.create(); | |
for (int i = 0; i < 100; i++) | |
{ | |
map.put("key:" + i, new Object()); | |
} | |
final String key = "special key"; | |
map.put(key, new Object()); | |
// We want to see if concurrent calls to map#put can cause map#get to return null | |
final long start = System.currentTimeMillis(); | |
final ExecutorService executor = Executors.newFixedThreadPool(1); | |
executor.submit(() -> { | |
while (System.currentTimeMillis() < start + 1000) | |
{ | |
map.put(key, new Object()); | |
} | |
}); | |
while (System.currentTimeMillis() < start + 1000) | |
{ | |
final Object retrievedObject = map.get(key); | |
if (retrievedObject == null) | |
{ | |
System.out.println("Race condition!"); | |
} | |
} | |
executor.shutdown(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Interesting!